2013-10-15 30 views
0

我在MySQL查詢看起來是這樣的:如何選擇SQL查詢正確的索引與ORDER BY子句(MySQL的)

SELECT t.field1, t.field2, t.field5, t.field6, t.field7 
FROM mytable as t 

WHERE t.field1 = a AND t.field2 = b AND t.field3 = c AND LENGTH(t.field4) > 0 

order by t.field5 desc 

LIMIT 0, 100; 

查詢不是非常快(10秒)和問題似乎是ORDER BY部分,沒有這一行查詢需要0.01秒,使用ASC而不是desc需要大約1秒。

我已經在查詢的WHERE/ORDER BY部分中以與它們在查詢(field1,field2,field3,field4,field5)中出現的順序相同的順序創建了索引,但它沒有被使用根據MySQL中的「解釋」。 (field1)有很高的基數(有100個不同值的整數)field2和field3是BOOLEAN,field5是一個高基數的字符串(但是LENGTH(field5)> 0使得基數低或?)。

單獨的field5上還有一個索引,這是查詢如上所示的唯一索引,刪除查詢的ORDER BY部分將使MySQL使用多列索引。

缺少什麼我在這裏?

編輯:這是實際的SQL:

SELECT t.shopid, t.isproduct, t.level, t.isduplicate, t.ref_id 

FROM urls as t 

WHERE t.shopid = 72 AND t.isproduct = 1 AND t.visited = 0 AND LENGTH(t.url) > 0 

ORDER BY t.level desc 

LIMIT 0, 100; 
+1

'LENGTH(t.field4)> 0'與'(t.field4不是null和t.field4!=「」)相同,那麼索引應該能夠使用它。 – Ashalynd

+1

當你開始進入複雜的查詢和優化時,上下文就是一切。我建議你用你的真實查詢來替換你的psuedo-sql示例,因爲幾乎不可能給出直接的答案(即知道這些字段中的一個是否是ID主鍵,當幫助時可能是非常寶貴的信息) – Lee

+0

不,那裏沒有聚集索引。我的方法是否正確地將ORDER-BY字段作爲索引的最後一個字段? 這可以解決使用子查詢,而不是? – Andreas

回答

0

它非常難以預測的查詢性能,而實際上不知道表的大小和數據類型。 Mysql優化器有自己的方法來決定使用哪個索引,這通常是非常好的。 您可以通過強制mysql使用FORCE INDEX來使用各種索引來實現命中和試用。 t.url上的索引永遠不能用於顯而易見的原因。

一件事,你可以嘗試是這樣的:一般不建議

select t.field1, t.field2, t.field5, t.field6, t.field7 from (SELECT t.field1, t.field2, t.field5, t.field6, t.field7 FROM mytable as t WHERE t.field1 = a AND t.field2 = b AND t.field3 = c AND LENGTH(t.field4) > 0) t order by t.field5 desc LIMIT 0, 100;

此,可以幫助你,如果輸出行數不是很大。

+0

優秀!現在它下降到0.2秒,這在這個特定的上下文中是可以接受的,我不期望數據會在未來增長,所以我想我會堅持這個解決方案。 非常感謝@azi,感謝Ashalynd,Lee&ypercube爲您的迴應和努力! /Andreas – Andreas