CẬP NHẬT với THAM GIA trên hồ sơ 100mm, làm thế nào để làm điều này tốt hơn? (trong T-SQL)


11

Tôi cần cập nhật 100 triệu bản ghi trong một bảng, thực tế, bình thường hóa bảng bằng cách thay thế giá trị varchar của một cột chỉ bằng một ID. (Tôi nói "thay thế" nhưng thực sự tôi đang viết ID vào một cột khác.)

Những gì tôi đang cố gắng đạt được là bình thường hóa tập dữ liệu. Dữ liệu chưa được chuẩn hóa không có chỉ mục. Suy nghĩ của tôi là tôi sẽ không xây dựng các chỉ mục trên các giá trị thô, chờ đợi, thay vào đó để lập chỉ mục các khóa ngoại sẽ thay thế các giá trị varchar bằng các giá trị nhỏ sau khi cập nhật hoàn tất.

UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)

Lý lịch

  • sử dụng MSSQL 2008 R2 trên Server 2008 R2
  • máy chủ có RAM 8 GB
  • máy chủ có một RAID10, 7200 RPM SATA (không tuyệt vời, tôi biết, trong sản xuất, nó sẽ chỉ đọc dữ liệu và không ghi dữ liệu; cộng với sự thiếu hụt HD gần đây khiến điều này trở nên cần thiết cho chi phí)
  • máy chủ có CPU Xeon lõi tứ kép
  • Máy không làm gì khác (hiện chỉ dành riêng cho dev, chỉ có quá trình này)
  • đăng nhập đơn giản được bật (? - nhưng nó vẫn đăng nhập để có thể quay lại?)
  • lưu ý rằng truy vấn tham chiếu hai DB khác nhau, với giá trị nào
  • "chiều rộng" của một bản ghi trong bảng được cập nhật là 455 byte

Tài nguyên trong quá trình thực thi

  • RAM vật lý được tối đa hóa
  • đĩa I / O được tối đa hóa
  • CPU hầu như không làm gì cả (điểm sặc là I / O)
  • thời gian chạy đã được 14 giờ và đếm!

Tôi nghi ngờ một số điều như tôi cần một chỉ mục trên dữ liệu thô, mặc dù tôi sẽ bỏ cột (AutoClassName) sau khi cập nhật chuẩn hóa. Tôi cũng tự hỏi liệu tôi có nên lặp lại bảng một lần thay vì THAM GIA, điều này có vẻ vô lý vào thời điểm tôi bắt đầu việc này, nhưng bây giờ có vẻ như nó sẽ nhanh hơn.

Làm cách nào để thay đổi phương pháp luận của tôi cho các cập nhật chuẩn hóa còn lại của tôi (tương tự như phương pháp này) nhanh hơn?

Câu trả lời:


7

Bạn đang cố gắng thực hiện điều này như một giao dịch (rất lớn). Thay vào đó, hãy cập nhật theo đợt nhỏ hơn.

Bạn cũng sẽ được hưởng lợi từ:

  • Một chỉ mục tạm thời trên AutoData.dbo.AutoClass.AutoClassName
  • Thêm RAM. Nhiều RAM hơn.

1
+1 Tôi đồng ý với việc cập nhật hàng loạt bằng cách sử dụng TOPmệnh đề. Đó là cách tiếp cận của tôi.
Thomas Stringer

Nếu tôi CẬP NHẬT HÀNG ĐẦU thì tôi sẽ cần mệnh đề WHERE (WHERE AutoClassID là NULL)? Mệnh đề WHERE sẽ không giới thiệu một hiệu suất mới (quét bảng mà tôi không thực hiện bây giờ). Không còn nghi ngờ gì nữa, nó sẽ làm giảm vấn đề RAM mà tôi gặp phải với THAM GIA.
Chris Adragna

Phản hồi của tôi đã quá hạn, nhưng trong trường hợp của tôi, SET ROWCOUNT đã chứng minh là hiệu quả nhất.
Chris Adragna

10

Tôi sẽ có một cách tiếp cận khác.

Thay vì cập nhật các bảng hiện có, chỉ cần xây dựng một bảng mới có những gì bạn cần trong đó.

Điều này gần như chắc chắn sẽ nhanh hơn:

SELECT DISTINCT
    AutoClassID,
    <Other fields>
INTO
    AutoDataImportStaging.dbo.Automobile
FROM
    AutoData.dbo.AutoClass

Như hiện tại được viết, có rất nhiều hoạt động hợp lý xảy ra:

  • Đọc tất cả các giá trị của A.AutoClassName
  • Đọc tất cả các giá trị của B.AutoClassName
  • So sánh giá trị A và B
  • Trong số các bộ phù hợp, đọc tất cả các giá trị của B.AutoClassID
  • Cập nhật các giá trị hiện có của A.AutoClassId thành giá trị B.AutoClassId thông qua bất kỳ chỉ mục nào tồn tại

Điều này nghe có vẻ như là một cách tiếp cận đơn giản, tốt đẹp, đặc biệt là với vấn đề I / O của đĩa tôi đang gặp phải. Cảm ơn bạn đã trả lời rất nhanh.
Chris Adragna

1
Tôi khuyên bạn nên kiểm tra kỹ xem bạn có đủ dung lượng trống trong tệp nhật ký và dữ liệu của mình không. Nếu các tập tin đang tự động phát triển, hiệu suất sẽ giảm dần. Tôi thường thấy mọi người chạy một số cập nhật lớn, một lần và tự động phát triển tệp nhật ký của họ mà không nhận ra.
eo biển darin

5

Vòng xuống bàn một hàng một lần, sẽ không nhanh hơn!

Như nghi ngờ và được xác nhận bởi bạn, điều này sẽ bị ràng buộc - có một đĩa, không gian đọc, ghi, nhật ký giao dịch và (bất kỳ) không gian làm việc tạm thời sẽ cạnh tranh cho cùng một i / o.

Phục hồi đơn giản vẫn sẽ ghi nhật ký các giao dịch, nhưng nhật ký sẽ bị xóa bởi một điểm kiểm tra. Có thể là kích thước nhật ký ban đầu và cài đặt tăng trưởng tự động của bạn đang khiến một số i / o bị chậm lại - nhật ký giao dịch sẽ cần tăng lên để phù hợp với các thay đổi.

Bạn đã thử lập chỉ mục trường AutoClassName chưa? Có bao nhiêu giá trị AutoClass khác nhau?

Bạn có thể cần phải bó các bản cập nhật, dựa trên các giới hạn của i / o của bạn. Vì vậy, cập nhật 1 triệu, điểm kiểm tra, lặp lại ....


Chỉ có 15 giá trị AutoClass khác nhau. Nhận xét của bạn xác nhận nhiều nghi ngờ của tôi (và đau!). Cảm ơn vì đã trả lời.
Chris Adragna

3

Tạo các chỉ mục cho các trường tham gia.

Bạn luôn có thể thả các chỉ mục khi bạn kết thúc.

Tôi sẽ rất ngạc nhiên nếu các chỉ mục không cải thiện đáng kể hiệu năng cập nhật.


Tôi chắc chắn các chỉ số sẽ cải thiện. Tôi cho rằng câu hỏi là liệu họ có cải thiện nhiều hơn thời gian cần thiết để tạo chỉ mục hay không (chỉ cho một lần sử dụng). Chắc là đúng. :)
Chris Adragna

3

Xuất theo cách bạn muốn, tạo một bảng mới và nhập lại. Là một Phần thưởng, bạn sẽ có một bản sao của dữ liệu là bản sao lưu, nếu điều kỳ diệu xảy ra.

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.