2010-04-14 14 views
10

Phương pháp hiệu quả nhất để tải khối lượng lớn dữ liệu từ CSV (3 triệu + hàng) vào cơ sở dữ liệu là gì.C# Nhập khối lượng lớn dữ liệu từ CSV vào cơ sở dữ liệu

  • Các dữ liệu cần phải được định dạng (ví dụ cột tên cần được chia thành tên đầu tiên và cuối cùng tên, vv)
  • tôi cần phải làm điều này trong một cách hiệu quả nhất tức là hạn chế thời gian có thể

Tôi đang đứng về phía tùy chọn đọc, chuyển đổi và tải dữ liệu bằng cách sử dụng ứng dụng C# theo từng hàng? Đây có phải là lý tưởng, nếu không, lựa chọn của tôi là gì? Tôi có nên sử dụng đa luồng?

+0

Mức độ ràng buộc về thời gian là bao nhiêu? – Jake

Trả lời

4

Bạn sẽ bị ràng buộc I/O, vì vậy đa luồng sẽ không nhất thiết làm cho nó chạy nhanh hơn.

Thời gian qua tôi đã làm điều này, đó là khoảng một chục dòng C#. Trong một chủ đề nó chạy đĩa cứng nhanh như nó có thể đọc dữ liệu từ đĩa cứng. Tôi đọc từng dòng một từ tệp nguồn.

Nếu bạn không muốn tự mình viết, bạn có thể thử các thư viện FileHelpers. Bạn cũng có thể muốn xem Sébastien Lorion's work. Trình đọc CSV của anh ấy được viết riêng để giải quyết các vấn đề về hiệu suất.

+0

vâng, thư viện C# io được thực hiện tốt với bộ đệm. Gần đây tôi đã phải chuyển đổi từ một csv này sang csv khác (1,5 m dòng) trong một cái gì đó giống như một phút. –

+1

Tôi cũng khuyên bạn nên sử dụng FileHelpers. Nó đã giúp tôi không phải viết một trình phân tích cú pháp để xử lý các giá trị có dấu phẩy trong chúng. Nếu CSV có bất kỳ chi tiết khó chịu nào như vậy, hãy xem xét FileHelpers. –

+0

tôi biết rằng trong quá khứ, thời gian tìm kiếm trên ổ đĩa là một vấn đề. trong trường hợp các tệp hình ảnh lớn, chúng tôi sẽ đọc từ một ổ đĩa và ghi vào một ổ đĩa khác để cắt giảm số lần định vị lại các đầu ổ đĩa. – yamspog

2

Tôi đồng ý với giải pháp của bạn. Đọc từng dòng một tập tin nên tránh việc đọc toàn bộ tập tin vào bộ nhớ cùng một lúc, điều này sẽ làm cho ứng dụng chạy nhanh và hiệu quả, chủ yếu dành thời gian đọc từ tập tin (tương đối nhanh) và phân tích các dòng . Một lưu ý cẩn thận tôi có cho bạn là để xem ra nếu bạn có nhúng dòng mới trong CSV của bạn. Tôi không biết liệu định dạng CSV cụ thể mà bạn đang sử dụng có thực sự tạo ra các dòng mới giữa các dấu ngoặc kép trong dữ liệu hay không, nhưng điều đó có thể gây nhầm lẫn cho thuật toán này, tất nhiên. Ngoài ra, tôi khuyên bạn nên trộn các câu lệnh chèn (bao gồm nhiều câu lệnh chèn trong một chuỗi) trước khi gửi chúng vào cơ sở dữ liệu nếu không có vấn đề trong việc truy xuất các giá trị khóa được tạo mà bạn cần sử dụng cho các khóa ngoại tiếp theo (hy vọng bạn không cần truy xuất bất kỳ giá trị khóa được tạo nào). Hãy ghi nhớ rằng SQL Server (nếu đó là những gì bạn đang sử dụng) chỉ có thể xử lý 2200 tham số cho mỗi lô, vì vậy hãy hạn chế kích thước lô của bạn để giải thích cho điều đó. Và tôi khuyên bạn nên sử dụng các câu lệnh TSQL tham số hóa để thực hiện chèn. Tôi nghi ngờ nhiều thời gian hơn sẽ được chi tiêu chèn hồ sơ hơn đọc chúng từ tập tin.

1

Bạn không biết bạn đang sử dụng cơ sở dữ liệu nào, nhưng ngôn ngữ bạn đề cập là C# Tôi sẽ giả sử SQL Server.

Nếu dữ liệu không thể nhập bằng BCP (có vẻ như nó không thể nếu nó cần xử lý quan trọng) thì SSIS có thể là tùy chọn nhanh nhất tiếp theo. Nó không phải là nền tảng phát triển đẹp nhất trên thế giới, nhưng nó cực kỳ nhanh. Chắc chắn nhanh hơn bất kỳ ứng dụng nào bạn có thể tự viết trong bất kỳ khung thời gian hợp lý nào.

+0

Tôi với Greg và JayRiggs trên trang này. Bỏ qua C# (trừ khi bạn đang viết một mô-đun CLR cho SQL Server). Hãy để SQL làm việc. Thật tốt khi làm việc với khối lượng dữ liệu khổng lồ từ các tệp, trong trường hợp bạn chưa từng nghe. ;) Điều đó sẽ giúp bạn tiết kiệm tất cả các loại đau đầu khi mở conxns, v.v. – jcolebrand

+0

Điều này khiến việc thử nghiệm đơn vị trở nên rất khó khăn? – guazz

+0

Đây không phải là loại vấn đề mà thử nghiệm đơn vị được sử dụng nhiều. Mọi người tập trung quá nhiều vào thử nghiệm đơn vị và bỏ qua bức tranh lớn hơn. Những gì bạn nên tìm kiếm để kiểm tra là dữ liệu được đưa vào cơ sở dữ liệu là chính xác, được cung cấp một bộ dữ liệu đã biết trong CSV và các trường hợp xấu được xử lý (cố định, loại bỏ hoặc không thành công) như mong đợi. Nếu bạn làm điều đó theo cách đó thì nó không thực sự quan trọng như thế nào nó được vào cơ sở dữ liệu. Vì vậy, từ bất kỳ quan điểm thực tế nào, tôi muốn nói rằng SSIS cũng có thể kiểm chứng như bất cứ điều gì khác. –

3

Bạn có thể sử dụng số csvreader để đọc nhanh CSV.

Giả sử bạn đang sử dụng SQL Server, bạn sử dụng csvreader CachedCsvReader để đọc dữ liệu vào một DataTable mà bạn có thể sử dụng với SqlBulkCopy để tải vào SQL Server.

+0

Đây là những gì tôi sử dụng. Tôi thích csvreader, nó là một cách rất thuận tiện để truy cập vào một tập tin phân cách. – galford13x

+0

+1 cho SqlBulkCopy – Kiril

0

BCP khá nhanh nên tôi muốn sử dụng để tải dữ liệu. Đối với thao tác chuỗi, tôi sẽ đi với một hàm CLR trên SQL khi dữ liệu ở đó. Đa luồng sẽ không giúp ích trong trường hợp này ngoại trừ việc thêm độ phức tạp và hiệu suất bị tổn thương.

0

Nếu bạn thực sự muốn làm điều đó trong C#, hãy tạo & điền một DataTable, cắt bớt bảng mục tiêu db, sau đó sử dụng System.Data.SqlClient.SqlBulkCopy.WriteToServer (DataTable dt).

+0

Thật không may, tôi cần cập nhật các bản ghi hiện có và dữ liệu sẽ được tải hàng ngày. – guazz