2014-11-21 89 views
0

我有以下選擇查詢:MySQL的選擇了結年齡

SELECT * FROM mytablename 
WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%')) 
ORDER BY c5 DESC 
LIMIT 0, 25; 

此表中有超過27萬行,但對於c1c2c3c4的索引。

問題是這個查詢需要20多分鐘才能執行。任何想法如何使這個更快?

我拿出ORDER BY,它在34秒完成 - 但如何與爲了做到這一點通過(c5是一個DATETIME列,其餘都是VARCHAR(80)

+0

'explain'對查詢說了什麼? – 2014-11-21 12:52:44

+0

您是否可以添加EXPLAIN語句的結果 – Pumpkin 2014-11-21 12:52:50

+0

如果指數是(c1,c4) – Strawberry 2014-11-21 12:54:13

回答

0

我不知道這件事。 ,請嘗試還是讓我知道,如果這個工程:

SELECT * FROM mytablename 
WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%')) 
and c4 = (SELECT MIN(c4) from mytablename) 
+0

不,還是5分鐘後... – 2014-11-21 13:06:03

1

如果查詢工作快沒有order by,然後使用子查詢:

SELECT t.* 
FROM (SELECT * 
     FROM mytablename 
     WHERE (c1 = 'text1' AND (c2 = 'text2' OR c3 = 'text2' OR c4 LIKE 'text2%')) 
    ) t 
ORDER BY c5 DESC 
LIMIT 0, 25; 

有一個關於性能的重要提示。當您刪除order by時,您正在獲取遇到的前25行。使用order by(在任一查詢中),您需要獲取整個匹配結果集。無論使用哪種方法,這可能需要更長的時間。

因此,爲了比較,您需要運行沒有order by而沒有limit的查詢。這需要多長時間?

+0

Wooohoo! 14秒:) – 2014-11-21 13:08:02

+0

我已經將c4更改爲c5,以使其成爲現實。 (我無法更新你的) – 2014-11-21 13:11:58

+0

@ConraddeWet我估計如果你把這個子查詢和我的答案結合起來,並在'datetime'上加上一個索引(如果它不存在的話),你可以把它更多的放在下面:) – funkwurm 2014-11-21 13:17:22

0

用來獲取行的關鍵是不一樣通過它可以削弱指數的有效性的訂單中使用的一個:

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

通過的聲明你取去除順序前25個結果,所以這可能不是一個好的基準。

說明語句會有所幫助,但看起來您需要一個包含您使用的所有內容的複合索引。

0

您的查詢必須選擇所有2700萬行並檢查WHERE,然後對其進行排序,然後僅給出前25行。但你真的很想要最近的25個項目。我的經驗是ORLIKE趨於緩慢下來,試試這個:

SELECT * FROM mytablename 
WHERE c1 = 'text1' AND 'text2' IN (c2, c3, LEFT(c4, 5)) 
ORDER BY c5 DESC 
LIMIT 0, 25; 

編輯:因爲你改變的c4/c5的錯誤,並c5有一個指數?幫助排序。

如果這還太慢,請看分區,你真的想查詢10年前的項目嗎?也許把它們放在不同的分區中。

+0

是的,所有列有單獨的索引(不是複合)。 – 2014-11-21 13:16:48