mysql強制使用索引

在公司後臺某模塊功能記錄日誌中有一個搜索功能,經過前段時間的產品使用時間區間進行搜索反饋有些卡頓,我發現這個搜索功能比較慢,要3秒左右才能出來,就決定對這裏作一下優化。mysql

經過分析代碼和SQL發現最核心的問題在於一個區間查詢耗時太長,耗時2秒多,因此我決定看看這裏能不能優化,其中核心SQL爲sql

SELECT  * FROM XXX_log WHERE (`ctime` BETWEEN '2017-09-11 09:34:13'  AND '2017-10-11 09:34:13')
and     id > 27851
AND column1 = 'xxx'
AND (column2 = 'null' OR LENGTH(column2) > 91)
ORDER BY  id DESC LIMIT 0, 30

這個查詢是一個簡單查詢,沒有聯表,就是單表的limit分頁查詢,外加一個時間區間和字段搜索,我經過SQL分析 explain 發現並未走索引,掃描區間也很大,因爲該表擁有接近100萬的記錄,查詢的掃描區間接近50萬,我感受這樣確定是效率不高的。運維

而後查詢了一下數據,發現耗時確實在2.6秒左右,我起初的設想是,column2字段查詢確定是無法改了 ,畢竟那涉及到之前的業務,該字段這樣搜索查詢確實有違常理,可是既然以前的功能已經這樣設計了,如今去作調整,反而有可能有問題,那麼就只有在 id ctime column1下手了,id它寫死了,定了某條記錄開始進行查詢,我猜想可能以前的數據是測試數據或者是廢棄數據,那既然有個標尺,就不去動它,column1是固定的查詢值,這樣也無法改,這樣的固定值在數據行中差別不明顯,加索引效果也不大,而後是ctime了,惟一能動文章的也只有它了。測試

而後我好好分析了一下這個模塊要實現的功能邏輯,就是查詢這段時間內符合要求的數據,這段時間,很明顯是一個月,能不能設定這個查詢區間只能查一個星期呢?優化

我改成一週內的時間區間查詢,確定能下降查詢的查詢區間啊,然而使人遺憾的是,這個下降查詢區間間隔,並無多大效果,最後無奈,我給ctime添加了一個 normal index btree索引,加了索引後,我本覺得一切都會好起來,誰知,explain後效果仍是那樣!spa

可能用到的索引keys  主鍵 ctime  ,然而呢 查詢區間仍是接近45萬,效果並不明顯,查詢時間也仍是2秒多,這可以讓我犯難了,一時一籌莫展,思考許久,忽然想到這感受是索引沒有真正生效致使的,那麼能不能強制告訴mysql使用某個索引了,讓他主動是走某個索引,而後我查詢了資料 找到了force index(強制要走的那個索引) ,我立刻就試了一下設計

SELECT  * FROM XXX_log force index(ctime) WHERE (`ctime` BETWEEN '2017-09-11 09:34:13'  AND '2017-10-11 09:34:13')
and     id > 27851
AND column1 = 'xxx'
AND (column2 = 'null' OR LENGTH(column2) > 91)
ORDER BY  id DESC LIMIT 0, 30

果真 explain分析以後 使用了ctime索引日誌

並且查詢區間下降到3萬多了,這個效果太明顯了,耗時下降到0.2秒左右,而後這個功能立刻從3秒才能打開下降到0.3秒就能打開了,這個優化效果令我很是滿意。code

在和運維討論該表的數據時,運維提供方案說,看到該表數據量龐大 接近100萬,而且時間不少是2015年 2016年的,他提出能夠轉移2015年 2016年的數據,我查看了一下,2015年和2016年的數據合計起來有70多萬了,佔據了絕大部分,若是轉移的話,確實有利於咱們查詢啊,比對啊,更新啊之類的,由於這是一張日誌表,在某個期間具備時效性,畢竟大部分時候今年不會再看去年前年的查詢數據了,因此我以爲這種作法也有依據,也合理,恰逢同事請假休息,此事等他回來再作討論。orm

本次想到強制使用索引,也是靈光一現,稍微有一些運氣在裏面的,否則還真很差解決這個問題,算是天公做美吧!遂感慨一首:

蒼茫青天顯神威,

攔路崔嵬面如灰。

忽而得來靈光現,

開山破土鎮邊陲!

相關文章
相關標籤/搜索