通過執行計畫,計算出mysql走的索引

2021-10-06 11:57:57 字數 1587 閱讀 5721

我們需要注意的幾個欄位是訪問型別type(all、index、range、 ref、eq_ref、const、system、null 從左到右,效能從差到好)、使用的索引key(key列顯示mysql實際決定使用的鍵(索引),必然包含在possible_keys中)、key_len(表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度)

其中key_len這個字段,可以通過數值判斷執行計畫中sql走的具體索引是什麼,那要如何計算呢?別急,待我娓娓道來。

我們可以通過一定的公式來通過key_len來計算sql走的索引,公式如下:

所有的索引字段,如果沒有設定not null,則需要加乙個位元組;

定長字段,int佔4個位元組,date佔3個位元組,datetime佔5個位元組(mysql5.5版本之前佔8個位元組,5.5之後版本佔5個位元組),char(n)佔n個字元

對於varchar(n),則佔n個字元+ 2個位元組;

不同的字符集,乙個字元占用的位元組數不同,latin1編碼,乙個字元占用乙個位元組,gbk編碼,乙個字元佔兩個位元組,utf-8編碼,乙個字元占用三個位元組;

那麼,上述的char、varchar索引長度的計算公式為:

長度 = (utf8mb4 = 4,utf8 = 3,gbk = 2,latin1 = 1) * 列長度 + 1(允許為null) + 2(變長列)

有以下sql:

其顯示的執行計畫為:

索引為:

可以看出,sql隨意輸入的branch_id在表中是不存在的,優化器走的索引為idx_orders_branch_id_complete_at,key_len = 130

對於索引中的兩個字段表結構如下:

根據公式:

key_len = 32 * 4(utf8mb4編碼) + 2 = 130

則該sql只走了branch_id這個索引,並沒有走完整的branch_id_complete_at索引,原因是因為我隨意輸入的branch_id在表中找不到相應資料,那麼我輸入乙個庫里存在的:

執行計畫為:

可以看出,索引走了我們的idx_branch_id_pay_at,ken_len長度為136,根據公式:

key_len = 32 * 4(utf8mb4編碼) + 2 + 5(date)+ 1(pay_at 可以為null) = 136

如果對於公式很熟悉的話,我們很快的能通過我們的key_len來判斷sql走了哪些索引,從而可以很快的找到解決方案,在實驗中,我發現datetime(n),如果n是0,則該字段為預設五個位元組,如果n為1、2,則字段為六個,3、4為七個。。。以此類推,感興趣的同學可以自己深究一下,好了,這次分享就到這裡了。

越知道你就越不知道,技術有限,理解有限,歡迎指正~

shell指令碼通過子網掩碼計算出掩碼位數

子網掩碼格式為255.255.255.0可以通過以下指令碼計算掩碼位數 bin sh maskdigits.sh mask maskdigits for num in a dowhile num 0 do echo n num 2 tmp num num num 2 done done echo g...

mysql如何進行統計求和並計算出名次

對應的mysql語句為 select personid,totalscore,personname,if de totalscore,rank rank num 1,rank rank,if de totalscore,num num,num 0 de totalscore from select ...

如何精確計算出乙個演算法的CPU執行時間

在程式中嵌入彙編語句,直接讀出cpu的機器週期。你需要多精確?gettickcount可以到18 20ms進度 timegettime可以到1ms精度 當然這些都不是c or c 標準支援的。那麼就要祭出最牛奔的方法,直接讀取cpu開機以來執行的機器週期數,一條彙編指令 rdtsc 就是 read ...