因專案需要,需要對資料庫一張表進行排序,取前10名
該錶基數6w, invite_sign = 'geight' 條件加上後資料為2w
未優化前,sql語句如下:
select * from wk_active_gt_sign_info where invite_sign = 'geight' order by invite_meet_num desc limit 10
執行效率為:80ms左右
explain該語句,發現明顯有filesort ,二次排序
查閱資料,由於where條件invite_sign是等於條件,故建立invite_sign + invite_meet_num 索引,執行效率明顯明顯優化為2ms左右
事情本該到此結束,但後有需求變動,當invite_meet_num 一樣的時候,需要第二個記錄時間的排序字段 —— remark1
故sql語句如下:
select * from wk_active_gt_sign_info where invite_sign = 'geight' order by invite_meet_numdesc,remark1 asc limit 10
建立invite_sign + invite_meet_num + remark1 索引
結果卻不如願,執行效率為80ms左右,有filesort
接著查閱資料,或者想著使用程式的角度去處理等等,都並不嚴謹,或效率較低等等。
而後突然一想,會不會是由於排序字段乙個正序,乙個倒序導致的索引無效,故使用如下sql測試
select * from wk_active_gt_sign_info where invite_sign = 'geight' order by invite_meet_numdesc,remark1 desc limit 10
執行效率超快,又回歸2ms左右,大喜
接下來就好辦了,remark1記錄資料的修改時間,本是正序,越早的時間越往前,那好辦了,使用乙個大的時間,對要記錄的時間進行乙個減法
使用這個time就可以倒序了。yes 搞定任務
總結:mysql where z和order by x,y 可以建立聯合索引 z+x+y來處理,但必須保證x,y兩個排序字段,同為倒序或正序。
接下拋個問題吧,10w的資料以內,查詢乙個實時的排名
sql為 select count(*)+1 from wk_active_gt_sign_info where invite_sign = 'geight' and (invite_meet_num >1 or (invite_meet_num =1 and remark1 >2))
執行效率為30ms左右,尚可以接受
有沒有更高效的解決辦法呢?
mysql欄位索引
drop table if exists auth assignment drop table if exists auth item child drop table if exists auth item drop table if exists auth rule create table a...
MySQL索引專題一 認識索引
想寫mysql的索引專題是源於之前自己在學習mysql索引時痛苦的經歷,你在網上搜尋關於mysql的索引的文章,大多是支離破碎,沒有系統性的對知識點的羅列堆砌,文章中會說明你要如何如何做,但是很少涉及去講為什麼要這麼做,哪些不能做,很難對mysql有乙個系統性的認知,學習如果沒有系統性的話,就很難在...
MySQL之索引 索引欄位的選取
日常在建資料表的時候,通常會在where,group by,order by等常用的字段上建立索引,當有多個字段時候,有一項原則就是該字段的去重後的值個數越多,索引建立的必要性越強。這裡建立一張資料表,有staff id和leader id兩個字段,通過explain分析可以驗證哪個欄位更適合做索引...