問題描述:數據表有3000萬行,單表分頁查詢,count時間在10s內,limit查詢需要一分鍾左右;表的索引非常多,幾乎每寫一個sql都會創建對應的索引,
sql類似:
select [data] from [table] where [condition] order by [sort] limit ?
盡管數據量很大,但也很慢的離譜了。查閱資料加上自己的嘗試,發現sql慢的原因是mysql優化器默認選擇了sort字段的索引,這個字段是個時間戳,區分度比較小,所以查詢就會很慢。
跟業務溝通,他們堅持不允許修改排序的字段。好吧,那只能嘗試改別的了。
第一種改法:給sql增加建議索引。一般情況下,加了建議索引,mysql就會走建議的索引,而不是自己去選擇。
select [data] from [table] use index(idx) where [condition] order by [sort] limit ?
當然也可以強制sql走建議的索引:
select [data] from [table] force index(idx) where [condition] order by [sort] limit ?
確實有效的加快了查詢速度。
但沒過幾天,又有一家客戶反饋慢,經常,也是選擇了慢的單字段的索引。出於其他客戶的查詢並不慢的考慮,只想給出問題的客戶查詢sql中指定索引,避免其他新的問題出現,但一家又一家也不是辦法啊。。。
第二種改法:
select [data] from [table] ignore index(idx) where [condition] order by [sort] limit ?
既然這個sort索引非常慢,那我們將這個慢索引刪除掉,mysql不就只能選擇其他索引了么。。嘗試去刪除索引,在阿里雲安全執行的加持下,刪了半個小時,還是失敗了。。體量太大,已經不允許增加索引或刪除索引了。
又想到,既然可以建議索引,那也應該可以禁止索引吧?
確實可以禁用索引,ignore index().禁止了慢的索引,跟刪除了索引是一個效果。加上一勞永逸
結論:
建索引的時候一定要慎重,區分度不大的字段不要建單索引,sql每次執行的時候只能走一個索引,不要給他太多選擇。。選擇題總會出錯的
有啟發的博文:
選擇了錯誤的慢索引:https://blog.csdn.net/weixin_39592315/article/details/113214658
索引命中規則:https://blog.csdn.net/weixin_40139740/article/details/84959075
優化sql:https://blog.csdn.net/qq_34412668/article/details/107962985
優化sql:https://blog.csdn.net/shengang1978/article/details/78595306
優化sql:https://developer.aliyun.com/article/279139