2013-01-12 31 views
0

我有一個系統使用order by來將數據返回給用戶界面;用戶可以以任何順序從十幾種不同的排序選項中進行選擇。MySQL使用多個索引的訂單

我有查詢

explain extended select t.* from task t order by create_date, due_date limit 5; 

+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra   | 
+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+ 
| 1 | SIMPLE  | t  | ALL | NULL   | NULL | NULL | NULL | 331233 | 100.00 | Using filesort | 
+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+ 
1 row in set, 1 warning (0.00 sec) 

我有CREATE_DATE索引以及DUE_DATE。我知道我可以創建一個多列索引;然而,由於有大約12種不同的排序選項,這意味着我將不得不創建超過一百個索引來涵蓋所有場景。

我閱讀了關於索引合併的問題,我相信這樣可以解決問題,因爲我可以爲可以排序的每列創建一個索引,但是我似乎無法讓它在「order by」部分工作查詢。

+0

您是否有真正的問題? – JohnFx

回答

1

即使沒有索引,DBMS也很擅長排序。請記住,額外的索引會減慢更新操作的速度,所以肯定會出現這樣的情況:表中的「索引太多」。

如果查詢很複雜,或者使用索引是最快的查詢計劃,則不能保證可以使用索引來呈現數據。

例如,您可能在ColumnA和ColumnC上進行排序的同時,對ColumnA(僅選擇表中的百萬行中的1/1000)有很好的過濾條件。在這種情況下,優化程序可能會更好地使用ColumnA上的索引並對1000個結果行進行排序,而不是按ColumnB和ColumnC上的索引順序讀取整個1,000,000行表,並在1000行中選擇滿足1,000過濾條件。

通常情況下,優化器比你知道的要好。不總是;甚至有時會出現錯誤,有時候會在實施過程中疏忽。但作爲第一個經驗法則,除非您可以重寫查詢以獲得相同的結果,否則優化程序很可能會做出體面的工作。 (如果你可以重寫查詢,得到的結果更快,那麼優化已經吹它,並且你已經有了一個bug報告了良好的基礎。)

0

您唯一能做的就是迫使指數

力指數INDEX_NAME訂單由

如果你想利用指標的優勢合併 然後嘗試使用聯合,或等,這將讓你使用多指標

永遠記住一個多索引會當兩個條件都是獨立的時候使用Ø對方那麼只有它會工作

在極少數情況下

,可以利用多指標

(這裏以上查詢我相信它不會工作)

0

嘗試這種解決辦法的:

explain extended select * from (select t.* from task t order by create_date limit 30) z order by create_date, due_date limit 5; 

它可以工作,當你有所有行的前30行內,而使用第一順序。 「Trick」是從主表中選擇一個simle查詢,並在30行集合上做更大的事情(連接,高級訂單,隨機等),比使用整個330K行表更快。