簡體   English   中英

MySQL:使用DISTINCT優化​​查詢

[英]MySQL: Optimize query with DISTINCT

在我的Java應用程序中,我發現了一個小的性能問題,這是由這樣簡單的查詢引起的:

 SELECT DISTINCT a 
   FROM table 
  WHERE checked = 0 
  LIMIT 10000

我在checked列上有索引。

在開始時,查詢非常快(即幾乎所有行都已checked = 0)。 但是當我標記越來越多的行時,查詢變得非常低效(最多幾分鍾)。

如何提高此查詢的性能? 我應該添加一個復雜的索引

  • a,檢查

更確切地說

  • 檢查,一個?

我的表有很多行,這就是為什么我不想手動測試它並希望有幸運的猜測。

我會在checked, a上添加一個索引checked, a 這意味着您已返回的值已在索引中找到,並且無需重新訪問該表即可找到它。 其次,如果您正在對表格進行大量更新,則表格和索引很可能在光盤上碎片化。 重建(壓縮)表和索引可以顯着提高性能。

您還可以使用重寫的查詢(以防優化器不理解它是等效的):

  SELECT a 
    FROM table 
   WHERE checked = 0 
GROUP BY a
   LIMIT 10000

添加在DISTINCT柱(化合物指數a在這種情況下)。 MySQL能夠將此索引用於DISTINCT

MySQL也可以在(a, checked)上獲得復合索引(a, checked) 順序很重要 ,DISTINCT列必須位於索引的開頭)。 嘗試兩者並將結果與​​您的數據和查詢進行比較。

(添加此索引后,您應該在EXPLAIN輸出中看到Using index for group-by 。)

請參閱手冊上的GROUP BY優化 DISTINCT非常類似於GROUP BY 。)

處理GROUP BY的最有效方法是使用索引直接檢索分組列。 使用此訪問方法,MySQL使用某些索引類型的屬性(按鍵排序)(例如,BTREE)。 此屬性允許在索引中使用查找組,而無需考慮索引中滿足所有WHERE條件的所有鍵

我的表有很多行<...>,其中幾乎所有行都檢查= 0

在這種情況下,似乎最好的指數是簡單的(a)

更新:

目前尚不清楚要檢查多少行。 從你的評論旁邊的問題:

在開頭0是100%行,但在一天結束時它將變為0%

這改變了一切。 所以@Ben有正確的答案。

我找到了一個完全不同的解決方案,可以解決這個問題。 我將簡單地創建一個包含所有可能的唯一“a”值的新表。 這將允許我避免DISTINCT

您沒有說明,但是您是否定期更新索引? 隨着基礎數據的變化,索引變得越來越不准確,處理越來越差。 如果您有一個已選中的索引,並且正在更新已檢查的索引,則需要確保定期更新索引。

暫無
暫無

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

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