簡體   English   中英

優化 MySQL 中的多對多查詢

[英]Optimising many-to-many query in MySQL

我有一個名為“ items ”的表,看起來像這樣......

id | name
––––––––––––
1  | APPLES 
2  | BANANAS
3  | ORANGES
4  | PEARS

...和一個名為“ pairs ”的連接表,在項目之間創建多對多關系...

id | item1_id | item2_id
––––––––––––––––––––––––
1  | 1        |  2 
2  | 1        |  4
3  | 2        |  3
4  | 2        |  4
5  | 4        |  3

我有以下查詢來查找與給定項目配對的項目...

SELECT * FROM items i
WHERE
  i.id IN (SELECT item1_id FROM pairs WHERE item2_id = 4)
OR
  i.id IN (SELECT item2_id FROM pairs WHERE item1_id = 4)

返回類似...

id | name
––––––––––––
1  | APPLES 
3  | ORANGES

...它完成了這項工作,但是,它運行得很慢(使用大約 100 個項目的小型測試數據集,1000 個配對已經花費了大約 75 毫秒)。

我的問題是——這是否可以進一步優化以加快速度(例如使用連接而不是嵌套查詢)?

謝謝你的幫助。

我認為在pairs(item2_id, item1_id)pairs(item1_id, item2_id)上有索引就足夠了——兩個單獨的索引。

然而,MySQL 有時IN用子查詢優化IN很時髦。 我會用exists寫這個:

SELECT i.*
FROM items i
WHERE EXISTS (SELECT 1
              FROM pairs p
              WHERE p.item2_id = 4 AND p.item1_id = i.id
             ) OR
      EXISTS (SELECT 1
              FROM pairs p
              WHERE p.item1_id = 4 AND p.item2_id = i.id
             );

這些保證使用索引。

內部查詢優化器在創建執行計划方面做得很好,盡管您可以查看計划並確定瓶頸。 像以不同的方式表達相同的查詢之類的事情在一天結束時通常不會產生巨大的差異。 即使是看起來非常瘋狂的查詢,您也會驚訝於優化器處理它們的能力如何,以及同一查詢的兩個看似不同的表達式如何最終導致相同的結果。 改為使用連接可能會導致相同或相似的執行計划。

所以我首先要做的是在您的 item1_id 列上創建一個索引,並在您的 item2_id 列上創建一個單獨的索引。 這將有助於提高那些 where 子句的性能。 然后,如果這仍然不能滿足您的要求,請查看MySQL 文檔的優化一章(無論您使用的是哪個版本的 MySQL),以完整了解可能的策略。 請注意,過早避免大量優化將使您受益,尤其是在您的應用程序很復雜的情況下。 一旦您的應用程序處於大部分工作狀態,您就可以更好地識別和解決瓶頸問題。 但在任何開發階段,指數始終是輕松且值得的第一步。

暫無
暫無

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

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