簡體   English   中英

MySQL 使用子選擇更新太慢

[英]MySQL update with subselect too slow

更新查詢的時間超過 20 分鍾時出現問題(之后我將其殺死)。

設想:

表一有大約 30 萬條記錄。

表二包含相同的記錄集(已復制),但有一個額外的字段,該字段需要包含與多個字段匹配的記錄的 id,並且具有另一個字段的最高值(一個分數)。 澄清一下,最終結果應該是包含 300K 記錄的表 2,每條記錄的 id 都是具有相同基本屬性集的另一條記錄,以及具有這些屬性的記錄集中的最高分數。

當我只將 2K 記錄而不是完整的 300k 記錄復制到表 2 中時,以下內容在 ~5 秒內完成。

UPDATE vtable2 v1 SET v1.buddy = (
    SELECT v2.id FROM vtable1 v2
    WHERE
    v2.group_id = v1.group_id AND
    // 6 more basic comparisons
    ORDER BY score DESC LIMIT 1
)

我需要為完整的 300K 記錄尋找伙伴。 連接和排序所涉及的所有字段都有索引。

非常感謝幫助。

MySQL 子查詢往往會慢一些。 在這種情況下,我更喜歡使用連接。 我不太清楚您的架構設計-但您可以嘗試這樣的事情-

UPDATE vtable2 v1
[INNER] JOIN vtable1 v2 
ON v2.group_id = v1.group_id
AND //OTHER JOIN CONDITIONS IF ANY
WHERE
//any other conditions
SET
v1.buddy = v2.id

PS - 當然你需要確保你的列上有正確的索引。 如果您需要這方面的幫助,您可以發布帶有解釋計划的整個查詢。

你可以用數字變量測試

 SELECT v2.id FROM vtable1 v2
WHERE
v2.group_id = 1 AND
// 6 more basic comparisons
ORDER BY score DESC LIMIT 1

無論如何,我認為使用 Join 更好,但我沒有架構數據庫。
也許您對 sql DB 上的索引有疑問。

您可以使用排除連接來查找 vtable1 中的行,以便在 vtable1 中找不到其他具有更高分數的行。

UPDATE vtable2 AS v1
INNER JOIN vtable1 AS v2a ON v1.group_id = v2a.group_id AND (...conditions...)
LEFT OUTER JOIN vtable1 AS v2b ON v1.group_id = v2b.group_id
  AND v2a.score < v2b.score AND (...conditions...)
SET v1.buddy = v2.id
WHERE v2b.group_id IS NULL;

您必須為外連接復制表達式中的所有其他條件; 您不能將它們放入 WHERE 子句中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM