慢查詢應該怎么去合理優(yōu)化
阿粉昨天把這個怎么把 SQL 是否命中是索引,以及把如何開啟開啟慢查詢的方法已經(jīng)分享給了大家,接下來我們就得分項一下,我們找到了自己的慢查詢的 SQL ,那就應該想辦法去優(yōu)化,怎么能去優(yōu)化自己的慢查詢呢?
索引和慢查詢
如何判斷是否為慢查詢?
MySQL判斷一條語句是否為慢查詢語句,主要依據(jù)SQL語句的執(zhí)行時間,它把當前語句的執(zhí)行時間跟 long_query_time 參數(shù)做比較,如果語句的執(zhí)行時間 > long_query_time,就會把這條執(zhí)行語句記錄到慢查詢?nèi)罩纠锩妗ong_query_time 參數(shù)的默認值是 10s,該參數(shù)值可以根據(jù)自己的業(yè)務需要進行調(diào)整。
這個 long_query_time 是阿粉昨天說過的,開啟慢查詢?nèi)罩?,就能查詢到?/p>
我們這個時候已經(jīng)找到了我們的慢查詢的語句,接下來是不是就應該看看我們寫的這個 SQL 是否命中了我們的索引呢?
如何判斷是否應用了索引?
這不就用到阿粉上一篇文章中的一個語句了,
explain
直接通過 explain 來分析查看,檢查結(jié)果中的 key 值,是否為NULL。
如果沒有出現(xiàn)自己創(chuàng)建的索引,那么很肯定,這個 SQL 是沒有走我們創(chuàng)建的索引的,那么他不慢 誰慢呢?
接下來阿粉給出一個 SQL ,看一下它是否會命中我們的索引呢?
select * from user where id > 2 ;
是否命中索引呢?
我們也都知道 ID 如果是主鍵的話,那么一定是有索引的,而這個 SQL 是否能命中索引,就得看你是怎么寫的,我可以告訴大家,這個語句,確實命中了索引,但是索引并沒有起作用。
為什么呢?
雖然使用了索引,但是還是從主鍵索引的最左邊的葉節(jié)點開始向右掃描整個索引樹,進行了 全表掃描,此時索引就失去了意義。
而像 select * from user where id = 2; 這樣的語句,才是我們平時說的使用了索引。它表示的意思是,我們使用了索引的快速搜索功能,并且有效地減少了掃描行數(shù)。
其實在這里,阿粉只想詮釋一個事情,那就是查詢是否使用索引,只是表示一個SQL語句的執(zhí)行過程;而是否為慢查詢,是由它執(zhí)行的時間決定的,也就是說是否使用了索引和是否是慢查詢兩者之間沒有必然的聯(lián)系。
我們在使用索引時,不要只關(guān)注是否起作用,應該關(guān)心索引是否減少了查詢掃描的數(shù)據(jù)行數(shù),如果 掃描行數(shù)減少了,效率才會得到提升。對于一個大表,不止要創(chuàng)建索引,還要考慮索引過濾性,過 濾性好,執(zhí)行速度才會快。
怎樣提高索引的過濾性能呢?
假如有一個5000萬記錄的用戶表,通過sex='男'索引過濾后,還需要定位3000萬,SQL執(zhí)行速度也 不會很快。其實這個問題涉及到索引的過濾性,比如1萬條記錄利用索引過濾后定位10條、100 條、1000條,那他們過濾性是不同的。索引過濾性與索引字段、表的數(shù)據(jù)量、表設計結(jié)構(gòu)都有關(guān) 系。
這就要讓我們具體的 SQL 具體的分析了,盡量能給我們的 Where 條件上面,增加索引,不管是普通索引還是聯(lián)合索引,盡量的把自己的索引建立在你能命中的情況下。
慢查詢是怎么導致的
慢查詢原因:
全表掃描:explain分析type屬性all 全索引掃描:explain分析type屬性index 索引過濾性不好:靠索引字段選型、數(shù)據(jù)量和狀態(tài)、表設計 頻繁的回表查詢開銷:盡量少用select *,使用覆蓋索引
所以你知道慢查詢應該怎么去優(yōu)化了么?
推薦閱讀:
不是你需要中臺,而是一名合格的架構(gòu)師(附各大廠中臺建設PPT)
企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案
論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?
企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!
