11MYSQL:慢查询以及优化步骤
MySQL記錄下查詢(xún)超過(guò)指定時(shí)間的語(yǔ)句,我們將超過(guò)指定時(shí)間的SQL語(yǔ)句查詢(xún)稱(chēng)為慢查詢(xún)。
1、查看時(shí)間限制
show variables like '%long%';
如果查詢(xún)超過(guò)long_query_time的時(shí)間就稱(chēng)為慢查詢(xún)。
2、查看數(shù)據(jù)庫(kù)的啟動(dòng)時(shí)間
show status like 'uptime%';
3、查看查詢(xún)語(yǔ)句條數(shù)
show status like 'com_Select';
4、獲取連接數(shù)
show status like 'connections';
5、設(shè)置慢查詢(xún)的時(shí)間
set long_query_time = 1;
6、以安全模式啟動(dòng)mysql服務(wù),慢查詢(xún)記錄將會(huì)寫(xiě)入日志之中。
開(kāi)啟慢查詢(xún)?nèi)罩?br /> 在MySQL的配置文件中加以下參數(shù)
log-show-queries = D:/MySQL/Log/mysqld-slow-query.log
long-query-time = 5
log-queries-not-using-indexes
闡述:
有關(guān)慢查詢(xún)?nèi)罩竟δ艽娣盼恢?#xff0c;該目錄文件一定要有寫(xiě)的權(quán)限。
可以用設(shè)置,系統(tǒng)會(huì)給一個(gè)缺省的文件host_name-show.log
long_query_time
SQL執(zhí)行時(shí)間閥值,默認(rèn)為10秒
注意一下三點(diǎn):
1、設(shè)置long_query_time這個(gè)閥值后,mysql數(shù)據(jù)庫(kù)會(huì)記錄運(yùn)行時(shí)間超過(guò)該值的所有SQL語(yǔ)句,但對(duì)于運(yùn)行時(shí)間正好等于long_query_time的情況并不會(huì)被記錄下來(lái)。也就是說(shuō),在mysql源碼里是判斷大于log_query_time,而非大于等于。
2、從MySQL5.1開(kāi)始,long_query_time開(kāi)始以微秒計(jì)算,這樣精確記錄SQL的運(yùn)行時(shí)間。
3、建議該時(shí)間不應(yīng)太小或太大,最好在5-10秒之間。當(dāng)然可以根據(jù)自己的情況來(lái)定。
log-queries-not-using-indexes
如果運(yùn)行的SQL語(yǔ)句沒(méi)有使用索引,則mysql數(shù)據(jù)庫(kù)同樣會(huì)將這條SQL語(yǔ)句記錄到慢查詢(xún)?nèi)罩疚募小?/strong>
查詢(xún)優(yōu)化神器 – explain命令
關(guān)于explain命令相信大家并不陌生,具體用法和字段含義可以參考官網(wǎng)explain-output,這里需要強(qiáng)調(diào)rows是核心指標(biāo),絕大部分rows小的語(yǔ)句執(zhí)行一定很快(有例外,下面會(huì)講到)。所以?xún)?yōu)化語(yǔ)句基本上都是在優(yōu)化rows。
慢查詢(xún)優(yōu)化基本步驟
0.先運(yùn)行看看是否真的很慢,注意設(shè)置SQL_NO_CACHE
1.where條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢(xún)語(yǔ)句的where都應(yīng)用到表中返回的記錄數(shù)最小的表開(kāi)始查起,單表每個(gè)字段分別查詢(xún),看哪個(gè)字段的區(qū)分度最高? ?查哪個(gè)字段時(shí)間比較長(zhǎng)????
2.explain查看執(zhí)行計(jì)劃,是否與1預(yù)期一致(從鎖定記錄較少的表開(kāi)始查詢(xún))
3.order by limit 形式的sql語(yǔ)句讓排序的表優(yōu)先查
4.了解業(yè)務(wù)方使用場(chǎng)景
5.加索引時(shí)參照建索引的幾大原則
6.觀察結(jié)果,不符合預(yù)期繼續(xù)從0分析
建索引的幾大原則
1.最左前綴匹配原則,非常重要的原則,mysql會(huì)一直向右匹配直到遇到范圍查詢(xún)(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整。
2.=和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢(xún)優(yōu)化器會(huì)幫你優(yōu)化成索引可以識(shí)別的形式
3.盡量選擇區(qū)分度高的列作為索引,區(qū)分度的公式是count(distinct col)/count(*),表示字段不重復(fù)的比例,比例越大我們掃描的記錄數(shù)越少,唯一鍵的區(qū)分度是1,而一些狀態(tài)、性別字段可能在大數(shù)據(jù)面前區(qū)分度就是0,那可能有人會(huì)問(wèn),這個(gè)比例有什么經(jīng)驗(yàn)值嗎?使用場(chǎng)景不同,這個(gè)值也很難確定,一般需要join的字段我們都要求是0.1以上,即平均1條掃描10條記錄
4.索引列不能參與計(jì)算,保持列“干凈”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡(jiǎn)單,b+樹(shù)中存的都是數(shù)據(jù)表中的字段值,但進(jìn)行檢索時(shí),需要把所有元素都應(yīng)用函數(shù)才能比較,顯然成本太大。所以語(yǔ)句應(yīng)該寫(xiě)成create_time = unix_timestamp(’2014-05-29’);
5.盡量的擴(kuò)展索引,不要新建索引。比如表中已經(jīng)有a的索引,現(xiàn)在要加(a,b)的索引,那么只需要修改原來(lái)的索引即可
總結(jié)
以上是生活随笔為你收集整理的11MYSQL:慢查询以及优化步骤的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 平安科技:传入一个只包含1-9的数字字符
- 下一篇: 25.C++:最通俗的讲解,什么是面向过