![](/img/trans.png)
[英]Optimize mysql query Suppliers <-> Products <-> Categories with DISTINCT
[英]MySQL: Optimize query with DISTINCT
在我的Java應用程序中,我發現了一個小的性能問題,這是由這樣簡單的查詢引起的:
SELECT DISTINCT a
FROM table
WHERE checked = 0
LIMIT 10000
我在checked
列上有索引。
在開始時,查詢非常快(即幾乎所有行都已checked
= 0)。 但是當我標記越來越多的行時,查詢變得非常低效(最多幾分鍾)。
如何提高此查詢的性能? 我應該添加一個復雜的索引
更確切地說
我的表有很多行,這就是為什么我不想手動測試它並希望有幸運的猜測。
我會在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.