性能優(yōu)化:減少或者消除那些對獲得查詢結(jié)果來說不必要的工作
程序性能瓶頸可能有很多因素:
①、外部資源章喉,比如調(diào)用了外部的WEB服務或者搜索引擎。
②身坐、應用需要處理大量的數(shù)據(jù)秸脱,比如分析一個超大的XML文件。
③部蛇、在循環(huán)中執(zhí)行昂貴的操作摊唇,比如濫用正則表達式。
④涯鲁、使用了低效率算法等巷查。
對MySQL查詢進行性能剖析有兩種方式:
1.剖析整個數(shù)據(jù)庫服務器,這樣可以分析出哪些查詢是主要的壓力來源抹腿。
2.定位具體需要優(yōu)化的查詢后岛请,可以對這些查詢進行單獨的剖析,分析哪些子任務是影響時間的主要消耗者警绩。
慢查詢?nèi)罩?/b>
#是否開啟慢查詢?nèi)罩荆?/on表示開啟崇败,0/off表示關閉。
show VARIABLES like 'slow_query_log';
#未使用索引的查詢也被記錄到慢查詢?nèi)罩局校琽n表示開啟后室,off表示關閉(默認值)缩膝。
show VARIABLES like 'log_queries_not_using_indexes';
#慢查詢閾值(秒級),當查詢時間大于設定的閾值時岸霹,記錄日志疾层。
show VARIABLES like 'long_query_time';
#慢查詢?nèi)罩敬鎯β窂?/b>
show variables like 'slow_query_log_file';
set global slow_query_log = on;
set global log_queries_not_using_indexes = on;
set global long_query_time = 0;
pt-query-digest
第一部分:總體統(tǒng)計結(jié)果
Exec time:執(zhí)行時間
Lock time:鎖定時間
Rows sent:發(fā)送行數(shù)
Rows examine:掃描行數(shù)
Query size:查詢字符數(shù)
第二部分:查詢分組統(tǒng)計結(jié)果
Rank:所有語句的排名,默認按查詢時間降序排列松申,通過--order-by指定
Query ID:語句的ID云芦,(去掉空格和查詢條件中的文本值,計算hash值)
Response:總的響應時間
time:該查詢在本次分析中總的時間占比
calls:執(zhí)行次數(shù)贸桶,即本次分析總共有多少條這種類型的查詢語句
R/Call:平均每次執(zhí)行的響應時間
V/M:方差均值比(Variance-to-mean)舅逸,也就是常說的離差指數(shù)。
Item:查詢對象
第三部分:每一種查詢的詳細統(tǒng)計結(jié)果
查詢各項數(shù)據(jù)的百分比皇筛、總數(shù)琉历、最小、最大水醋、平均旗笔、95%等各項目的統(tǒng)計,包括SQL執(zhí)行次數(shù)拄踪、執(zhí)行時間蝇恶、鎖占用時間、發(fā)送行數(shù)惶桐、掃描行數(shù)撮弧、查詢字符數(shù),表格中也統(tǒng)計了查詢涉及的數(shù)據(jù)庫姚糊、查詢時間直方圖等信息贿衍。
掃描的行數(shù)(Rows Examine)遠遠大于發(fā)送的行數(shù)(Rows sent) , 有問題, 需要優(yōu)化救恨, 索引利用差
Query_time distribution:查詢時間分布圖——————直方圖
哪些SQL需要優(yōu)化:
??????????? 1.查詢次數(shù)多贸辈,且每次查詢占用時間長的SQL:通常為pt-query-digest分析的前幾個查詢
??????????? 2.IO大的SQL:注意pt-query-digest分析中的Rows examine
??????????? 3.未使用索引的SQL:通過pt-query-digest分析中的Rows examine與Rows Send對比
剖析單條查詢
使用SHOW PROFILE
#開啟:
SET profiling = 1;
#查看開啟工具后的每條SQL執(zhí)行總體情況
SHOW PROFILES;
#根據(jù)query_id查看某個查詢的詳細時間耗費
SHOW PROFILE FOR QUERY 1;
#查看cpu、IO等信息
SHOW PROFILE BLOCK IO,CPU FOR QUERY 1;
#對每一個子任務的花費時間進行已統(tǒng)計排序
SELECT state, SUM(duration) AS Total_R,
? ROUND(100 *SUM(duration) / (SELECT SUM(duration) FROM information_schema.profiling WHEREquery_id = 1), 2) AS Pct_R,
? COUNT(*) as Calls,SUM(duration) /COUNT(*) AS "R/Call"
? FROMinformation_schema.profiling
WHERE query_id = 1 GROUP BY state ORDER BY total_r DESC;
Creating sort index:當前的SELECT中需要用到臨時表在進行ORDER BY排序肠槽。建議:創(chuàng)建適當?shù)乃饕?/b>
Sending data:發(fā)送數(shù)據(jù)
table lock:表鎖擎淤。
System lock:系統(tǒng)鎖。建議確認是由于哪個鎖引起的秸仙,通常是因為MySQL或InnoDB內(nèi)核級的鎖引起的
Sorting result:結(jié)果的排序
copying to tmp table:將數(shù)據(jù)復制到臨時表
Creating tmp table:創(chuàng)建臨時表
執(zhí)行計劃:Explain
table:對應的表
type:連接類型(system揉燃、const、eq_ref筋栋、ref、range正驻、index弊攘、all)
possible_keys:可能使用的索引
key:實際使用的索引
key_len:使用索引長度
rows:預計掃描行數(shù)
Extra:解析查詢的額外信息(using index抢腐、using where、using temporary襟交、using filesort)
連接類型(type)
#all? 全表掃描
explain select * from address;
#index 全索引掃描
explain select city_id from address;
#range?? < >??? in()?between?? 根據(jù)索引范圍查找
explain select * from address where city_id>2;
#ref? 根據(jù)索引 查詢匹配某個值的行
explain select * from address where city_id=200;
#eq_ref
explain select a.* from store a INNER JOIN address b using(address_id)where b.address='47 MySakila Drive';
#const
explain select * from address where address_id=1;
MySQL解析額外信息(Extra)
1迈倍、Using index:列數(shù)據(jù)僅僅使用了索引中的信息而沒有讀取實際的表(不回表)
Select address_idfrom address where address_id=1
2、Using where:MySQL服務器將在存儲引擎檢索行后捣域,通過Where子句條件進行過濾
Select * fromaddress where city_id>12;
3啼染、Using temporary:MYSQL需要創(chuàng)建一個臨時表來存儲結(jié)果,用于排序
Select DISTINCTdistrict from address;
4焕梅、Using filesort:MySQL將對結(jié)果進行外部排序
Select * fromaddress??order by district;