我使用下面的查詢上的相對大的表(〜2000萬行):如何使用組合索引進行昂貴的聚合查詢?
SELECT
MAX(`col_1`)
FROM `table`
WHERE
col_2 = X AND
col_3 = Y AND
col_4 = Z
我已經在列組合索引COL_2,col_3和col_4和上COL_1的單獨一個,但查詢是仍然比沒有WHERE
部分的相同查詢慢多個數量級。
如何使用索引來改善這方面的性能?
我使用下面的查詢上的相對大的表(〜2000萬行):如何使用組合索引進行昂貴的聚合查詢?
SELECT
MAX(`col_1`)
FROM `table`
WHERE
col_2 = X AND
col_3 = Y AND
col_4 = Z
我已經在列組合索引COL_2,col_3和col_4和上COL_1的單獨一個,但查詢是仍然比沒有WHERE
部分的相同查詢慢多個數量級。
如何使用索引來改善這方面的性能?
由於How MySQL Uses Indexes下記載:
MySQL使用索引這些操作:
[ deletia ]
因此,MySQL不能使用的是您在col_1
尋找MAX(col_1)
當你申請一個過濾器定義的簡單指標:它必須轉而掃描所有匹配的行(雖然它可以按照col_1
的降序排列,按照該簡單索引進行排序),如查詢的EXPLAIN
輸出所示。
您應該使用(col_2, col_3, col_4, col_1)
上的索引。
謝謝,這推動了查詢時間的水平,它沒有'哪裏' 部分 – Thomas
您可以嘗試在第四位索引col_1
,但很大程度上取決於表的結構(即單行的權重)。在col_1
上計算MAX
時,如果沒有WHERE
,則通過索引立即可以獲得信息(只需將其保持在原來的左側即可)。
添加一個WHERE
,它不再是如此。您的查詢可能已被優化。進一步的改進可能(可能)可以通過知道X,Y和Z的類型及分佈進行
(A笨例如:說col_2
,col_3
和col_4
已知是在範圍(-255,+ 255 ),那麼你可以考慮添加一個額外的非規格化列,並保留(((col_1+255)*512+(col_2+255))*512+(col_3+255))
,並在該索引和col_1
上編制索引,甚至可以基於該索引進行集羣如果可以找到一個結果數據類型合理的內射函數,你經常在X,Y和Z上運行「精確」查詢,即沒有WHERE col_2 BETWEEN X1 AND X2
東西)。
你是否檢查過該索引是否與「解釋」一起使用?索引是否按這個確切順序包含列? – j0nes
你使用什麼引擎? MyISAM或InnoDB? – Kermit
引擎是InnoDB。我還有一個關於所有4列的索引,是否必須按照特定的順序? – Thomas