如果B列中的值不在索引頁可用,那麼MySQL將需要訪問在基礎表的頁面。還有沒有謂詞過濾哪些行正在考慮,這意味着MySQL看到所有行都需要返回。這可以解釋爲什麼索引沒有被使用。
還要注意的是LIMIT
操作都在聲明的最後處理,因爲幾乎在執行計劃中的最後一步,有一些例外。
8.2.1.3. Optimizing LIMIT Queries http://dev.mysql.com/doc/refman/5.5/en/limit-optimization.html
我懷疑你的查詢可以利用覆蓋索引,例如「ON hugetable (A,B)
」,以避免排序操作。
缺席覆蓋索引,你可以嘗試重寫查詢這樣的事情,看看這是否會利用在A列的索引,並避免對數百萬行的排序操作(獲得第一個51萬行返回按順序):
SELECT i.B
FROM (SELECT j.A
FROM hugeTable j
ORDER
BY j.A
LIMIT 10000 OFFSET 500000
) k
JOIN hugetable i
ON i.A = k.A
ORDER
BY k.A
我建議你剛上線視圖的查詢做一個EXPLAIN
(別名爲K),看看它是否顯示「Using index
。」
外部查詢可能還有「Using filesort
」操作,但至少,這將是隻10,000行。
(注意:您可能希望在外部查詢嘗試一個 「ORDER BY i.A
」 代替 「k.A
」,看看是否有差別。)
附錄
不是專門針對你的問題,而是從查詢性能的角度來看,如果這是「分頁」一組行,另一個需要考慮的選項是進入「下一頁」頁面,使用「A
」的值在上一個查詢中檢索到的最後一行作爲t的「起點」他下一行。
原始查詢看起來是越來越「第51頁」(每頁10,000行,第51頁將行510001通520000)。
如果你還回「A」的價值,並保持對於最後一行。爲了得到「下一步」頁面,查詢實際上可能是:
SELECT i.B, k.A
FROM (SELECT j.A
FROM hugeTable j
WHERE j.A > $value_of_A_from_row_520000
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LIMIT 10000
) k
JOIN hugetable i
ON i.A = k.A
ORDER
BY k.A
如果您還不停的價值訴求從「第一」行,你可以利用它來進行備份頁面。這實際上只適用於前進一頁或後一頁。跳轉到不同的頁面,將不得不使用查詢的原始形式,對行進行計數。