Trước hết, để giải quyết các câu hỏi cụ thể mà bạn nêu ra:
-
Như được ghi lại trong
CREATE INDEX
Cú pháp :Do đó, trước khi xem xét
HASH
lập chỉ mục, người ta nên biết rằng nó là chỉ có sẵn trongMEMORY
vàNDB
công cụ lưu trữ:vì vậy thậm chí có thể không phải là một lựa chọn cho bạn.Hơn nữa, hãy lưu ý rằng lập chỉ mục trên các kết hợp của
ID
vàLookup
một mình có thể không tối ưu, vìWHERE
của bạn vị ngữ cũng lọc trêntablea.Elg_IDpart1
vàtableb.IDpart1
—Bạn cũng có thể hưởng lợi từ việc lập chỉ mục trên các cột đó. -
Với điều kiện là công cụ lưu trữ hỗ trợ các loại chỉ mục mong muốn, bạn có thể kết hợp chúng khi bạn thấy phù hợp.
-
Bạn có thể sử dụng gợi ý chỉ mục để buộc MySQL sử dụng các chỉ mục khác nhau cho những chỉ mục mà trình tối ưu hóa đã chọn.
-
Nó thường là đủ thông minh, nhưng không phải lúc nào cũng vậy. Tuy nhiên, trong trường hợp này, nó có thể đã xác định rằng bản chất của các chỉ mục để tốt hơn là sử dụng những chỉ mục mà nó đã chọn.
Bây giờ, tùy thuộc vào phiên bản MySQL mà bạn đang sử dụng, các bảng dẫn xuất từ truy vấn con có thể không có bất kỳ chỉ mục nào trên chúng có thể được sử dụng để xử lý thêm:do đó, kết hợp với b
có thể yêu cầu quét toàn bộ bảng dẫn xuất đó (không có đủ thông tin trong câu hỏi của bạn để xác định chính xác mức độ của vấn đề này có thể là bao nhiêu, nhưng schema1.tableb
có 1,5 triệu bản ghi cho thấy nó có thể là một yếu tố quan trọng).
Xem Tối ưu hóa truy vấn con để biết thêm thông tin.
Do đó, người ta nên cố gắng tránh sử dụng các bảng dẫn xuất nếu có thể. Trong trường hợp này, có vẻ như không có bất kỳ mục đích nào đối với bảng dẫn xuất của bạn vì người ta có thể chỉ cần tham gia schema1.tablea
và schema1.tableb
trực tiếp:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND a.ID IS NOT NULL
AND b.IDpart1 IS NOT NULL
AND b.Lookup IS NOT NULL
ORDER BY ID, Lookup
Thứ duy nhất bị mất là bộ lọc cho DISTINCT
các bản ghi, nhưng các bản ghi trùng lặp sẽ chỉ (cố gắng) ghi đè các giá trị đã cập nhật với các giá trị tương tự lần nữa — điều này sẽ không ảnh hưởng gì, nhưng có thể đã tỏ ra rất tốn kém (đặc biệt là với rất nhiều bản ghi trong bảng đó).
Việc sử dụng ORDER BY
trong bảng dẫn xuất là vô nghĩa vì không thể dựa vào nó để đạt được bất kỳ thứ tự cụ thể nào cho UPDATE
, trong khi trong phiên bản sửa đổi này, nó sẽ đảm bảo rằng mọi bản cập nhật ghi đè lên những bản trước đó sẽ diễn ra theo thứ tự đã chỉ định:nhưng điều đó có cần thiết không? Có lẽ nó có thể được gỡ bỏ và lưu vào bất kỳ thao tác sắp xếp nào.
Người ta nên kiểm tra các vị từ trong WHERE
mệnh đề:tất cả chúng có cần thiết không (NOT NULL
kiểm tra a.ID
và b.Lookup
, ví dụ, là thừa vì bất kỳ NULL
nào như vậy các bản ghi sẽ bị loại bỏ bởi JOIN
vị ngữ)?
Nhìn chung, điều này để lại cho chúng ta:
UPDATE schema1.tablea a
JOIN schema1.tableb b USING (ID, Lookup)
SET a.Elg_IDpart1 = b.IDpart1,
a.Elg_IDpart2 = b.IDpart2
WHERE a.Elg_IDpart1 IS NULL
AND b.IDpart1 IS NOT NULL
Chỉ khi hiệu suất vẫn không đạt yêu cầu thì người ta mới nên xem xét thêm việc lập chỉ mục. Các cột có liên quan (tức là những cột được sử dụng trong JOIN
và WHERE
vị ngữ) được lập chỉ mục? Các chỉ mục có được chọn để sử dụng bởi MySQL không (lưu ý rằng nó chỉ có thể sử dụng một chỉ mục cho mỗi bảng để tra cứu:để kiểm tra cả JOIN
vị ngữ và các vị từ bộ lọc:có lẽ bạn cần một chỉ mục tổng hợp thích hợp)? Kiểm tra kế hoạch thực thi truy vấn bằng cách sử dụng EXPLAIN
để điều tra thêm các vấn đề như vậy.