Cách nhanh nhất để chèn số lượng lớn các hàng là gì?


27

Tôi có một cơ sở dữ liệu nơi tôi tải các tệp vào một bảng phân tầng, từ bảng phân tầng này tôi có 1-2 phép nối để giải quyết một số khóa ngoại và sau đó chèn các hàng này vào bảng cuối cùng (có một phân vùng mỗi tháng). Tôi có khoảng 3,4 tỷ hàng cho ba tháng dữ liệu.

Cách nhanh nhất để đưa các hàng này từ dàn vào bảng cuối cùng là gì? Tác vụ luồng dữ liệu SSIS (sử dụng chế độ xem làm nguồn và có hoạt động tải nhanh) hoặc lệnh Chèn VÀO CHỌN ....? Tôi đã thử Nhiệm vụ luồng dữ liệu và có thể nhận được khoảng 1 tỷ hàng trong khoảng 5 giờ (8 lõi / 192 GB RAM trên máy chủ) mà tôi cảm thấy rất chậm.


1
Là các phân vùng trên các nhóm fileg riêng biệt (và trên các filegroup đó trên các đĩa vật lý khác nhau)?
Aaron Bertrand

3
Một tài nguyên thực sự tốt Hướng dẫn hiệu suất tải dữ liệu . Điều này giải quyết rất nhiều tối ưu hóa hiệu suất bạn có thể làm, ví dụ: Kích hoạt TF610 , Sử dụng BCP OUT / IN, SSIS, v.v. Bạn chỉ cần làm theo các khuyến nghị và kiểm tra nó trong môi trường của mình.
Kin Shah

@Aaron vâng, mỗi tháng một filegroup, 12 san lun được đính kèm để tất cả jan đi trên một lun, v.v. Không chắc có bao nhiêu đĩa mỗi lun nhưng nên có rất nhiều.
nojetlag

Vâng tôi thực sự có nghĩa là "bộ đĩa" và có lẽ cũng có thể đề cập đến bộ điều khiển, có thể bị bão hòa.
Aaron Bertrand

@Kin đã xem hướng dẫn nhưng có vẻ đã lỗi thời: "Đích máy chủ SQL là cách nhanh nhất để tải dữ liệu hàng loạt từ luồng dữ liệu Dịch vụ tích hợp sang SQL Server. Đích này hỗ trợ tất cả các tùy chọn tải hàng loạt của SQL Server - ngoại trừ ROWS_PER_BATCH . " và trong SSIS 2012, họ đề xuất đích OLE DB để có hiệu suất tốt hơn.
nojetlag

Câu trả lời:


25

Một cách tiếp cận phổ biến:

  1. Vô hiệu hóa / thả chỉ mục / ràng buộc trên bảng đích.
  2. INSERT dbo.[Target] WITH (TABLOCKX) SELECT ...
  3. Tất nhiên, với tín dụng cho JNK, bạn có thể thực hiện các thao tác trên theo từng đợt n, điều này có thể làm giảm căng thẳng cho nhật ký giao dịch và tất nhiên có nghĩa là nếu một số đợt thất bại, bạn chỉ phải bắt đầu từ đợt đó. Tôi đã viết blog về điều này (trong khi tham chiếu đến việc xóa, các khái niệm cơ bản tương tự được áp dụng) ở đây: http://www.sqlperformance.com/2013/03/io-subystem/chunk-deletes
  4. Kích hoạt lại / tạo lại các chỉ mục / ràng buộc trên bảng đích (và có lẽ bạn có thể trì hoãn một số trong số chúng, nếu chúng không cần thiết cho tất cả các hoạt động và điều quan trọng hơn là nhanh chóng lấy dữ liệu cơ sở trực tuyến).

Nếu các phân vùng của bạn là vật lý và không chỉ logic, bạn có thể có được một chút thời gian bằng cách có các quy trình khác nhau đồng thời phân vùng các phân vùng khác nhau (tất nhiên điều này có nghĩa là bạn không thể sử dụng TABLOCK/ TABLOCKX). Điều này giả định rằng nguồn cũng phù hợp cho nhiều quá trình lựa chọn mà không chồng chéo / khóa, v.v. và làm cho phía đó của hoạt động chậm hơn (gợi ý: tạo một chỉ mục cụm trên nguồn phù hợp với sơ đồ phân vùng trên đích).

Bạn cũng có thể xem xét một cái gì đó nguyên thủy hơn nhiều, như BCP OUT/BCP IN .

Tôi không biết rằng tôi sẽ nhảy đến SSIS để giúp đỡ việc này. Có thể có một số hiệu quả ở đó, nhưng tôi không biết rằng nỗ lực này biện minh cho việc tiết kiệm.


2
Đừng mù quáng thả chỉ mục (đặc biệt là chỉ mục cụm) nếu dữ liệu của bạn không được sắp xếp. Việc bỏ chỉ mục và hy vọng tạo lại một chỉ mục được nhóm có thể là một sai lầm lớn vì nó có thể tiêu tốn cả dung lượng đĩa lớn cộng với lượng thời gian khổng lồ. Tôi không phải là người đầu tiên trải nghiệm sai lầm như vậy. Nhìn vào mô tả "Kế hoạch B" trong bài viết này sqlmag.com/t-sql/ . Tác giả đã có cùng một vấn đề.
jyao

10

Nhìn vào vấn đề của bạn từ góc độ SSIS, tôi cảm thấy lý do điều này có thể mất nhiều thời gian là vì bạn đã không thực hiện theo đợt. Điều này có thể dẫn đến quá nhiều hàng lấp đầy đường ống SSIS và kết quả là có thể cản trở hiệu suất SSIS của bạn. Những gì bạn cần làm là thay đổi hàng của bạn trên mỗi cài đặt hàng loạt và có thể là kích thước cam kết chèn tối đa của bạn. Bây giờ những gì bạn thiết lập cũng sẽ phụ thuộc vào dung lượng bộ nhớ có sẵn cho máy chủ SSIS của bạn? Tốc độ đĩa của phiên bản SQL Server của bạn là bao nhiêu? Cách tốt nhất để làm điều này là thử nghiệm. Cho phép sử dụng 10.000. Điều này sẽ gửi một lô đến máy chủ 10.000 tại một thời điểm, do đó giữ cho đường ống của bạn không bị quá tải và sẽ giúp chạy quá trình này nhanh hơn. Các cài đặt này được đặt ở đích OLEDB của bạn.

Điểm đến OLEDB

Nếu đó là một vấn đề, bạn cũng có thể thêm một tác vụ SQL thực thi trước và sau để làm như @AaronBertrand gợi ý và xóa / thêm bất kỳ chỉ mục hoặc ràng buộc nào vào bảng.


1
Có một câu hỏi tuyệt vời về những gì "tải nhanh" đòi hỏi ở nơi khác trên DBA.SE: dba.stackexchange.com/questions/141430/ Lỗi .
Jon của tất cả các giao dịch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.