Cập nhật một bảng với hàng triệu bản ghi, đã 4 ngày rồi.


12

Tôi hiện đang cập nhật một bảng với hàng triệu bản ghi, đã 4 ngày và truy vấn vẫn đang được thực thi.

Tôi đã kiểm tra màn hình hoạt động cho thấy truy vấn đang chạy.

Trong nhật ký sự kiện không có lỗi nào cả.

Hiệu suât khôn ngoan:

  • Tempdb trong đĩa A (không gian trống 850 gb)
  • tệp cơ sở dữ liệu trong đĩa B (dung lượng trống 750 gb)
  • Ram 16 GB

Xin đề nghị tôi nên làm gì?

Truy vấn

UPDATE
    dbo.table1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
    dbo.table2 t2
WHERE
    LEFT(dbo.test1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

Câu trả lời:


3

Có một chi tiết thú vị cho truy vấn này mà tôi không phát hiện ra lúc đầu. Nhờ câu trả lời của Fabricio Araujo, giờ tôi mới thấy: bạn đang truy cập hai bảng. Tôi chưa bao giờ thấy loại sử dụng này của bản cập nhật trước đây và tôi không khuyên bạn nên sử dụng nó. Tôi khuyên bạn nên sử dụng cú pháp nối trực quan hơn cho mỗi câu trả lời của Fabricio.

Nguyên nhân có thể là sự nối giữa hai bảng tạo ra một số lượng cực lớn các hàng. Điều này có thể xảy ra nếu LEFT(col, 3)biểu thức tạo ra các giá trị trùng lặp. Nếu nó tạo ra 10 bản sao, điều này sẽ dẫn đến 100000x100000 = 10000000000 hàng trong kết quả tham gia.

Tôi không nghĩ rằng lập chỉ mục đóng một vai trò ở đây. SQL Server có thể giải quyết phép nối không liên kết này chỉ tốt với hàm băm hoặc phép nối. Không mất 4 ngày.

Nguyên nhân khác có thể là sự đánh giá thấp về số lượng đầu vào hoặc đầu ra tham gia. SQL Server có thể đã chọn tham gia vòng lặp.

Vì đây vẫn chỉ là suy đoán, tôi khuyên bạn nên đăng kế hoạch truy vấn sẽ làm sáng tỏ vấn đề này.


8

Truy vấn này yêu cầu bạn quét mọi hàng trong bảng vì

  • Tôi đoán Procodet hoặc CarrierCode không được lập chỉ mục
  • Ngay cả khi chúng được lập chỉ mục, bạn có TRÁI là một chức năng trên một vị từ WHERE
  • Và bạn cũng có THU THẬP, đây thực sự là một chức năng trên một vị từ WHERE

"một hàm trên một vị từ WHERE" có nghĩa là các chỉ mục sẽ không được sử dụng

Nếu bạn bó nó (giả sử vào CẬP NHẬT HÀNG ĐẦU (10000) ... VÀ costPercentage IS NULL) thì bạn cần một chỉ mục trên costPercentage điều này giả sử bạn đang đặt nó.

Các giải pháp duy nhất tôi thấy là

  • điền vào một bảng mới theo đợt, dựa trên, ví dụ, khóa chính
  • tạo các cột được lập chỉ mục, được tính toán để ẩn các biểu thức TRÁI và THU THẬP, sau đó chạy cập nhật

@ gbn .. cảm ơn đó là một ý tưởng tuyệt vời .. nhưng vì dữ liệu là hàng triệu quá trình này sẽ mất thời gian .... tôi đã nghĩ có thể có một cách để tìm hiểu tiến trình truy vấn không?
May mắn

1
Tại sao phải mất 4 ngày để quét "hàng triệu" hàng? Cho dù các hàng có thể được lập chỉ mục lớn và nặng đến mức nào, điều đó sẽ không mất 4 ngày. Căn nguyên của vấn đề vẫn chưa được biết.
usr

1
Nếu bạn thường xuyên xử lý dữ liệu lớn, vậy còn bạn có được một máy chủ phù hợp cho điều đó thì sao? Đặt dữ liệu vào ổ SSD, v.v.
TomTom

1
@Lucky chắc chắn. Tôi đã giải quyết câu trả lời. Có một cái gì đó sai mà chúng tôi chưa tìm thấy. Nó không phải là truy vấn của chính nó hoặc phần cứng. Điều đó sẽ không bao giờ lên đến 4 ngày thời gian.
usr

3
Cho rằng truy vấn đang nối một phần 3 ký tự của một cột thành một phần 3 ký tự của một cột khác, kết quả sẽ có nhiều khả năng chứa các bản sao. Điều này tệ hơn nhiều so với việc chỉ cập nhật hàng triệu hàng. Tôi cá là nó đang quét qua một bàn làm việc trong hàng tỷ.
datagod

4

Trước hết, thay đổi truy vấn thành:

UPDATE t1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
  dbo.table1 t1
  inner join dbo.table2 t2
    on LEFT(t1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

Theo như được chỉ ra bởi bài đăng đầu tiên của Jeff Moden trong cuộc thảo luận đó , truy vấn của bạn rất giống với câu hỏi mà anh ấy đã cảnh báo về "hiệu ứng Halloween".

Sau đó, các biểu thức TRÁI phải được lập chỉ mục. Câu trả lời của gbn cung cấp cho bạn các gợi ý về cách làm điều đó.

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.