Kích thước lô được khuyến nghị là SqlBulkCopy
gì? Tôi đang tìm một công thức chung mà tôi có thể sử dụng làm điểm khởi đầu để điều chỉnh hiệu suất.
Kích thước lô được khuyến nghị là SqlBulkCopy
gì? Tôi đang tìm một công thức chung mà tôi có thể sử dụng làm điểm khởi đầu để điều chỉnh hiệu suất.
Câu trả lời:
Tôi có một tiện ích nhập trên cùng một máy chủ vật lý với phiên bản SQL Server của tôi. Sử dụng một tùy chỉnh IDataReader
, nó phân tích cú pháp các tệp phẳng và chèn chúng vào cơ sở dữ liệu bằng cách sử dụng SQLBulkCopy
. Một tệp thông thường có khoảng 6 triệu hàng đủ điều kiện, trung bình có 5 cột văn bản thập phân và văn bản ngắn, khoảng 30 byte mỗi hàng.
Với tình huống này, tôi nhận thấy kích thước hàng loạt là 5.000 là sự thỏa hiệp tốt nhất giữa tốc độ và mức tiêu thụ bộ nhớ. Tôi bắt đầu với 500 và thử nghiệm với lớn hơn. Tôi nhận thấy 5000 nhanh hơn trung bình 2,5 lần so với 500. Việc chèn 6 triệu hàng mất khoảng 30 giây với kích thước lô là 5.000 và khoảng 80 giây với kích thước lô là 500.
10.000 nhanh hơn không thể đo lường được. Di chuyển lên 50.000 đã cải thiện tốc độ thêm một vài điểm phần trăm nhưng nó không đáng để tăng tải trên máy chủ. Trên 50.000 cho thấy tốc độ không được cải thiện.
Đây không phải là công thức, nhưng là một điểm dữ liệu khác để bạn sử dụng.
Đây là một vấn đề tôi cũng đã dành một thời gian để xem xét. Tôi đang tìm cách tối ưu hóa việc nhập các tệp CSV lớn (16+ GB, hơn 65 triệu bản ghi và đang phát triển) vào cơ sở dữ liệu SQL Server 2005 bằng ứng dụng bảng điều khiển C # (.Net 2.0). Như Jeremy đã đã chỉ ra , bạn sẽ cần phải thực hiện một số tinh chỉnh cho hoàn cảnh cụ thể của bạn, nhưng tôi sẽ khuyên bạn có một kích thước hàng loạt ban đầu là 500, và kiểm tra đánh giá cao cả trên và dưới này.
Tôi đã nhận được khuyến nghị kiểm tra các giá trị từ 100 đến 1000 cho kích thước lô từ bài đăng trên diễn đàn MSDN này và đã rất nghi ngờ. Nhưng khi tôi kiểm tra kích thước lô từ 100 đến 10.000, tôi thấy rằng 500 là giá trị tối ưu cho ứng dụng của tôi. Giá trị 500 cho SqlBulkCopy.BatchSize
cũng được đề xuất ở đây .
Để tối ưu hóa hơn nữa hoạt động SqlBulkCopy của bạn, hãy xem lời khuyên MSDN này ; Tôi thấy rằng việc sử dụng SqlBulkCopyOptions.TableLock giúp giảm thời gian tải.
Như những người khác đã nêu, nó phụ thuộc vào môi trường của bạn, cụ thể là khối lượng hàng và độ trễ mạng.
Cá nhân, tôi sẽ bắt đầu với việc đặt thuộc BatchSize
tính thành 1000 hàng và xem nó hoạt động như thế nào. Nếu nó hoạt động, thì tôi tiếp tục tăng gấp đôi số hàng (ví dụ: 2000, 4000, v.v.) cho đến khi hết thời gian.
Ngược lại, nếu thời gian chờ xảy ra ở 1000, thì tôi giảm số hàng xuống một nửa (ví dụ: 500) cho đến khi nó hoạt động.
Trong mỗi trường hợp, tôi tiếp tục tăng gấp đôi (nếu thành công) hoặc giảm một nửa (nếu không thành công) sự khác biệt giữa mỗi trong hai kích thước lô đã thử cuối cùng cho đến khi tìm thấy điểm hấp dẫn.
Các yếu tố khác để xem xét là bao lâu để sao chép một đơn lô hàng. Thời gian chờ sẽ xảy ra nếu loạt hàng được sao chép vượt quá thuộc BulkCopyTimeout
tính theo mặc định là 30 giây. Bạn có thể thử nhân đôi thuộc BulkCopyTimeout
tính lên 60 giây. Điều này cho phép một khoảng thời gian dài hơn để sao chép một tập hợp hàng loạt lớn hơn. Ví dụ: một loạt 50.000 hàng có thể mất khoảng 40 giây chỉ vượt quá giới hạn thời gian 30 giây, vì vậy việc tăng nó lên đến 60 giây có thể giúp ích cho hiệu suất.
Tất cả điều này phụ thuộc vào việc thực hiện của bạn.
Bạn có thể mong đợi loại tốc độ nào trên mạng của mình? Bạn đang sử dụng nó trong Biểu mẫu hoặc ASP.Net? Bạn có cần thông báo cho người dùng về tiến độ không? Quy mô của tổng công việc là gì?
Theo kinh nghiệm của tôi, chạy sao chép hàng loạt mà không có kích thước hàng loạt được chỉ định sẽ gây ra các vấn đề về thời gian chờ. Tôi muốn bắt đầu với 1000 bản ghi và thực hiện một số điều chỉnh từ đó.
tôi đã thử nhiều kích cỡ, trong trường hợp của tôi thì 5000 là tốt