Tôi muốn một số đầu vào về một vấn đề tôi đang gặp phải. Chúng tôi có một phần mã mà chúng tôi lặp lại trong suốt các quy trình được lưu trữ của mình và mỗi lần mất khá nhiều thời gian để xử lý và khi kết hợp, số lần đọc chạy vào hàng trăm triệu trên một bộ hàng trăm nghìn Mục. Về cơ bản chúng ta có Vật phẩm và Vật phẩm có thể có tới 12 máy, mỗi máy có trạng thái riêng.
Đây là các cấu trúc bảng (đơn giản hóa):
CREATE TABLE dbo.ItemMachineState
(
[itemID] [int],
[machineID] [int],
[stateID] [int]
)
CREATE TABLE dbo.Transition
(
[machineID] [int] NOT NULL,
[eventID] [int] NOT NULL,
[stateID] [int] NOT NULL,
[nextStateID] [int] NOT NULL
)
Điều gì xảy ra là, trong quá trình xử lý, chúng ta tạo một bảng #temp mà chúng ta làm việc và cuối cùng nó có một eventID cho mỗi Mục. Bảng tạm thời đó sau đó được nối lại vào ItemState và Transition, như vậy:
UPDATE dbo.ItemState
SET stateID = tr.nextStateID
FROM #temp t
JOIN dbo.ItemMachineState ist ON ist.itemID = t.itemID
JOIN Transition tr ON tr.stateID = ist.stateID AND
tr.machineID = ist.machineID AND
tr.eventID = t.eventID
Vì vậy, eventID, mà chúng tôi tính toán, sẽ xác định điều gì sẽ xảy ra với Máy của một vật phẩm nhất định, tùy thuộc vào trạng thái của chúng. Mỗi vấn đề là một sự kiện có thể điều khiển 0 hoặc nhiều trạng thái máy trong một chuyển động, nếu sự kiện đó có liên quan để kết hợp cụ thể của nhà nước và máy.
Đây là một ví dụ về một trong những thay đổi trạng thái này:
ItemID 3468361 đầu tiên trông như thế này trong ItemMachineState ...
itemID machineID stateID
----------- ----------- -----------
3468489 12 4
3468489 14 113
3468489 15 157
3468489 16 165
3468489 18 169
3468489 19 165
3468489 20 157
3468489 21 165
3468489 23 173
3468489 24 173
3468489 26 9
3468489 36 9
Chúng tôi thực hiện một số công việc và cuối cùng có bảng #temp có ItemID và EventID ...
itemID eventID
----------- -----------
3468489 64
Sau đó, chúng tôi tham gia cả hai bảng này vào Transition, có vẻ như thế này cho sự kiện cụ thể nàyID:
machineID eventID stateID nextStateID
----------- ----------- ----------- -----------
13 64 73 79
13 64 74 79
13 64 75 79
13 64 76 79
13 64 77 79
13 64 78 79
13 64 187 79
13 64 188 79
13 64 189 79
13 64 190 79
13 64 191 79
36 64 9 79
36 64 194 79
36 64 196 79
36 64 208 79
36 64 210 79
36 64 213 79
36 64 218 79
46 64 73 79
47 64 73 79
70 64 73 79
70 64 75 79
70 64 76 79
70 64 77 79
70 64 78 79
Để tất cả chúng cùng nhau:
SELECT t.itemID, t.eventID, ist.machineID, ist.stateID, tr.nextStateID
FROM #temp t
JOIN dbo.ItemMachineState ist ON ist.itemID = t.itemID
JOIN Transition tr ON tr.stateID = ist.stateID AND
tr.machineID = ist.machineID AND
tr.eventID = t.eventID
itemID eventID machineID stateID nextStateID
----------- ----------- ----------- ----------- -----------
3468489 64 36 9 79
Vì vậy, trong ví dụ cụ thể này, Sự kiện này chỉ liên quan đến một Máy cho Mục này. Đó là stateID được cập nhật từ 9 đến 79 trên machineID 36 và mọi thứ khác vẫn giữ nguyên cho Mục này.
Tôi muốn đề xuất về cách tiếp cận khác nhau này. Chúng ta không thể di chuyển khỏi cấu trúc bảng, nhưng chúng ta có thể thay đổi cách chúng ta sắp đặt trạng tháiID thành nextStateID trong quá trình chuyển đổi / sự kiện. Như bạn có thể thấy ở trên điều này hoạt động bằng cách loại bỏ; chúng ta cần trạng thái hiện tại và máy để tìm ra trạng thái tiếp theo là gì, cho máy đó, cho sự kiện đó. Trong một số trường hợp, điều này sẽ không cập nhật bất cứ điều gì, lần khác nó sẽ cập nhật nhiều máy trong một lần và chúng tôi thích khả năng đó. Tôi không nghĩ rằng giải pháp gọn gàng nhất cho vấn đề này sẽ được tìm thấy bằng cách thay đổi chỉ mục hoặc thêm gợi ý truy vấn và chúng tôi cần một cách tiếp cận mới giới hạn số lần đọc và thời gian xử lý, nhưng cung cấp cho chúng tôi cùng chức năng.
Tôi muốn tránh đưa các chỉ mục và như vậy vào cuộc thảo luận này vì sau đó tôi phải sử dụng các ví dụ thực tế, gây ô nhiễm bản chất của những gì tôi đang cố gắng hỏi ở đây, tôi đã thay đổi tên của các cột và bảng để đơn giản hóa câu hỏi của mình. Trong mọi trường hợp, ở đây bạn đi:
Gói truy vấn http://pastebin.com/xhPa4t8d , tạo và lập chỉ mục các tập lệnh http://pastebin.com/sp70QuEJ
Lưu ý rằng trong kế hoạch truy vấn, chúng tôi buộc INNER LOOP THAM GIA. Nếu để lại một THAM GIA đơn giản, truy vấn sẽ mất nhiều thời gian hơn để xử lý.
Sử dụng chỉ mục @wBob UNIQUE CLUSTERED, trước:
Sử dụng OPTION (MERGE JOIN, HASH JOIN)
kết quả này kế hoạch và kết quả thực hiện:
Sẽ cập nhật với thông tin khác trong thời gian ngắn
FROM #Event AS e INNER LOOP JOIN EFT.AssetState AS ast
, bạn có thể sử dụng gợi ý truy vấn OPTION (LOOP JOIN, QUERYTRACEON 8649, QUERYTRACEON 4199);
. Tổng bộ nhớ trên máy chủ và bộ nhớ tối đa cũng như cài đặt Max dop là bao nhiêu? Ngoài ra, bạn có thể kiểm tra điều kiện cụ thể bằng cách sử dụng if exists (select .. some criteria = true) then update else do nothing
cùng với cập nhật hàng loạt.
OPTION (MERGE JOIN, HASH JOIN)
cùng một lúc? Bạn đã thử OPTION (LOOP JOIN, QUERYTRACEON 8649, QUERYTRACEON 4199);
chưa
dbo.ItemState
ddl và một số dữ liệu. bạn có thể sử dụng sqlfiddle.com để thiết lập repro. Ngoài ra, có bất kỳ chỉ mục, FK, kích hoạt nào được xác định trên các bảng đó không? Bạn có thể đăng một kế hoạch thực hiện xml thực tế (sử dụng pastebin và liên kết nó ở đây). Điều đó sẽ giúp bạn có được câu trả lời tốt hơn và nhanh hơn :-)