簡體   English   中英

MySQL 查詢優化。 避免臨時和文件排序

[英]MySQL query optimization. Avoiding temporary & filesort

目前我有一個近 100 萬行的表,我需要從中查詢。 我需要做的是從給定的產品ID列表中對它們包含的產品數量進行堆棧排名。

SELECT count(productID) AS commonProducts, packageID
FROM supply
WHERE productID IN (2,3,4,5,6,7,8,9,10) 
GROUP BY packageID 
ORDER BY commonProducts 
DESC LIMIT 10

查詢工作正常,但我想改進它。 我在 productID 和 packageID 上嘗試了一個多列索引,但它似乎尋求更多的行,而不僅僅是為每個列設置一個單獨的索引。

MySQL說明

select_type: SIMPLE
table: supply
type: range
possible_keys: supplyID
key: supplyID
key_len: 3
ref: null
rows: 996
extra: Using where; Using temporary; Using filesort

我主要擔心的是查詢正在使用臨時表和文件排序。 我怎么能 go 關於優化這個查詢? 我認為最大的問題是 count() 和 count() 結果的 ORDER BY。

您可以使用Dependent Subquery刪除臨時表:

select * from 
  (
   SELECT count(productID) AS commonProducts, s.productId, s.packageID 
   FROM supply as s
   WHERE EXISTS
   (
      select 1 from supply as innerS 
        where innerS.productID in (2,3,4,5,6,7,8,9,10) 
          and s.productId = innerS.productId 
   )
   GROUP BY s.packageID
  ) AS t
ORDER BY t.commonProducts 
DESC LIMIT 10

內部查詢鏈接到外部查詢並保留索引。 您會發現任何對 commonProducts 進行排序的查詢,包括上述查詢,都將使用文件排序,因為count(*)絕對沒有被索引。 但不要害怕,filesort 只是一個花哨的排序詞——mysql 可以選擇使用有效的內存排序——無論你現在使用它還是作為索引臨時表的合並排序,你都將擁有在某處支付排序費用。 但是,這種情況非常好,因為文件排序一旦達到您設置的LIMIT就會停止排序。 它不會對整個 commonProducts 列表進行排序。

更新

如果要一直運行此查詢,我建議(不要太花哨)在供應表上設置觸發器以更新跟蹤此類計數器的合法表。

創建一個臨時結果集:

SELECT  TMP.*
FROM (  SELECT count(productID) AS commonProducts, packageID
        FROM supply
        WHERE productID IN (2,3,4,5,6,7,8,9,10)
        GROUP BY packageID 
) AS TMP 

ORDER BY commonProducts 
DESC LIMIT 10

也許這不是最優雅的方式,我不能保證它會更快,因為一切都取決於您的特定數據。 但在某些情況下,這會產生更好的結果:

SELECT count(*) AS commonProducts, packageID
FROM (
    SELECT packageID FROM supply WHERE productID = 2
    UNION ALL
    SELECT packageID FROM supply WHERE productID = 3
    UNION ALL
    .
    .
    .
    SELECT packageID FROM supply WHERE productID = 10
) AS t
GROUP BY packageID
ORDER BY commonProducts DESC
LIMIT 10

暫無
暫無

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

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