最近新工作忙活告一段落,開始著手梳理老系統的業務邏輯寫成文件,沒想到看到了祖傳**:儲存過程。雖然我沒寫過儲存過程不過好在我sql功底不錯,也能看得懂,我把儲存過程的sql整理出來,發現有一斷sql慢查詢嚴重,經過explain分析發現有一小段sql掃瞄了全表,心裡想著難道沒給這個欄位加索引?於是看看對應的表發現雖然沒有專門為這個欄位加索引,不過這個欄位有組合索引,
了解過組合索引的同學知道有個最左原則:
比方說我給a,b,c三個字段建立組合索引,實際上是建立了3個索引:
因此沒必要再次建立a和a,b索引,這樣的好處能否實現索引覆蓋避免回表。
但是為什麼這個字段沒有用到索引呢???
建立索引時還有乙個原則是不要給那些值分不太均勻的字段建立索引,比如想gender(性別),要麼是m要麼是f,或者有同學用1,2區分,這不重要,因為這個性別欄位的值分布大約各為50%,這樣的話索引是不生效的,因為mysql執行優化器判斷走索引的收益大不大,一般來說走索引檢索出的結果佔總量的30%(記不清了???)才會走索引。
但是我這個欄位是倉庫id啊,一般來說唯一的,怎麼肥四??我找個值試了一下:
此時的我陷入了沉思,怎麼肥四?於是我去表結構看了看這個字段,頓時晴天霹靂,我勒個擦,這尼瑪是varchar字串型別啊!!!
然後機智的我把值前後加上引號變成字串:
美滋滋,到此謎底揭開了,因為傳值時候要注意值型別,如果資料庫是字串型別你傳整型或者倒過來,雖然不會報錯,但是mysql會隱式轉譯,這樣索引會失效,這個道理呢我是知道的,但我在這裡犯下的錯誤是:先入為主!!!,因為這個老系統不是我做的,因此我也不知道是字串型別,自以為就當成了整型。
先入為主很可怕,有時候我們在做邏輯時候會因為先入為主產生很多bug,當我們轉測時候發現很多先入為主的邏輯錯誤在修改**就很麻煩了,因此我們在做邏輯時候不確定的一定要先確定好。
好了,最後本文章我們提煉下關於索引的3個知識點:
組合索引最左原則
不要在值分布就均勻的字段上建立索引
條件傳值型別一定要匹配,避免mysql隱式轉換
mysql的聯合索引 mysql聯合索引詳解
聯合索引又叫復合索引。對於復合索引 mysql從左到右的使用索引中的字段,乙個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index a,b,c 可以支援a a,b a,b,c 3種組合進行查詢,但不支援 b,c進行查詢 當最左側欄位是常量引用時,索引就十分有效。兩個或更多個...
mysql中的聯合索引
聯合索引又叫復合索引。對於復合索引 mysql從左到右的使用索引中的字段,乙個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index a,b,c 可以支援a a,b a,b,c 3種組合進行查詢,但不支援 b,c進行查詢 當最左側欄位是常量引用時,索引就十分有效。如 建立 姓...
MySQL的聯合索引和覆蓋索引
關於mysql的聯合索引,覆蓋索引一直濛濛噠,所以寫點東西來熟悉一下 首先建立乙個表orders,結構如下 create table orders order id int unsigned auto increment,order status int notnull,total price in...