2011-11-18 105 views
0

我有一個緩慢(1.4秒)的查詢,一直在困擾着我一段時間,所以我只是覺得我會把它,看看是否有人可以幫助我優化我的索引,加快它:優化mysql索引

select sql_calc_found_rows t.id, q.im_id, concat(t.si_id, ' ', t.de), q.date, q.das, q.dac, u.name, q.ac, q.st 
from t300q q 
left join t300 t on t.id = q.con_id 
left join users u on u.id = q.user_id 
order by q.date desc limit 0,100 

sql中解釋結果:

SIMPLE q ALL  89126 Using filesort 
SIMPLE t eq_ref PRIMARY PRIMARY 4 db.q.con_id 1 
SIMPLE u eq_ref PRIMARY PRIMARY 4 db.q.user_id 1 

會話統計:

Handler_read_first = 0 
Handler_read_key = 177934 
Handler_read_next = 23 
Handler_read_prev = 679 
Handler_read_rnd = 15 
Handler_read_rnd_next = 89127 

,我有以下指標:

t.id - primary key 

q.con_id | 
q.date  | - all form a single index 
q.user_id | 

u.id - primary key 

,你可以看到從處理程序統計表q的大小爲89126行。

這不是一個大問題,但如果可能的話,我希望速度低於1秒。

+0

'q.date '應該有索引? http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/ – osgx

+0

完全不回答你的問題,但是你有選擇在PostgreSQL下嘗試相同的查詢嗎?我通常可以將10個表的連接數以百萬計的行數減少到幾百毫秒。在需要時自行組合索引是非常好的。 –

+0

不幸的是我沒有postgresql – mulllhausen

回答

1

查詢很慢,因爲您沒有日期索引。由於日期處於中間位置,因此無法使用複合索引。將日期移至現有索引中的第一個字段或創建獨立索引。

+0

我試着將日期移動到索引中的第一個位置,但查詢仍然需要1.4秒,然後我嘗試爲q.date本身添加一個新的索引(並且使其他索引與q .date,q.con_id,q.user_id),但查詢仍需要大約1.4秒。感謝您的想法,儘管 – mulllhausen

+0

查詢需要多長時間與解決問題無關。重要的是執行計劃是否有任何改變。哪裏? –

+0

好點。使用這三個關鍵定義中的任何一個都不會改變'explain select'輸出。不過我只是嘗試在另一個開發數據庫上使用更高版本的MySQL完全相同的事情和查詢在0.4秒內執行,所以它必須是... – mulllhausen

1

順便說一句,mysql只對3列索引的前兩列使用相等。最後一列可以使用範圍查詢。

即:

WHERE x=? AND y=? order by z; 

將使用的列的索引(X,Y,Z)(自Z可以是不等)。

嘗試將'date'移動到第3列並重寫查詢。

如果這樣做不起作用,那麼mysql在智能上不足以處理連接中的con_id和user_id ..也許你可以重寫它,以便這些連接條件在where子句中發生。

+0

好吧我試着恢復只包含以下字段的單個索引按照這個順序:q.con_id,q.user_id,q.date,但速度仍然在1.4秒左右:P不知道要重新編寫查詢 - 我會保持這種最後的手段,因爲它聽起來像不好的SQL練習。無論如何感謝提示 – mulllhausen

0

嘗試在數據庫上觸發OPTIMIZE或ANALYZE,但確保在只有少量請求的時間觸發此操作,或者在服務器上沒有請求正在執行時避免出現任何問題對出現的你可能會看到這個鏈接這個語句的更多信息:

http://dev.mysql.com/doc/refman/5.6/en/analyze-table.html http://dev.mysql.com/doc/refman/4.1/en/optimize-table.html