1.慢查詢日誌mysql
MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中
#查看慢查詢是否開啓 >show variables like '%slow_query_log%'; #開啓慢查詢(默認是關閉) >set global slow_query_log=1; #設置時間閥值(默認是10s) >set global long_query_time=1; #未使用索引的查詢也被記錄到慢查詢日誌中(默認關閉) >set global log_queries_not_using_indexes=1;
分析日誌 mysqldumpslow /var/lib/mysql/ArchLinux-slow.log Count: 1 #訪問計數 Time=0.00s (0s) #平均查詢時間(總查詢時間) Lock=0.00s (0s) #平均鎖定時間(總鎖定時間) Rows_sent=1000.0 (1000) #平均返回記錄數(總返回記錄數) Rows_examined=1000.0 (1000) #平均掃描過的行數(總掃描過的行數) Rows_affected=0.0 (0) #平均更新行數(總更新行數)
分析日誌(percona-toolkit) pt-query-digest /var/lib/mysql/ArchLinux-slow.log 開始總的摘要信息 # 170ms user time, 10ms system time, 26.00M rss, 213.39M vsz --此工具執行日誌分析時的所用時間、內存資源(rss物理內存佔用大小,vsz虛擬內存佔用大小) # Current date: Mon Jul 28 09:55:34 2014 --分析時的系統時間 # Hostname: lump.group.com --進行分析的主機名 # Files: mysql-slow.log --分析的日誌文件名稱 # Overall: 5 total, 4 unique, 0.02 QPS, 0.04x concurrency --文件中總共的語句數量,惟一的語句數量(對語句進行了格式化),QPS(每秒查詢數(queries per second)),併發數 # Time range: 2014-07-28 09:50:30 to 09:54:50 --記錄日誌的時間範圍 # Attribute total min max avg 95% stddev median --total總計,min最小,max最大,avg平均,95%把全部值從小到大排列,位於95%的那個數 –Exec time:語句執行時間 –Lock time:鎖佔有時間 –Rows sent:發送到客戶端的行數 –Row examine:掃描的行數(SELECT語句) –Row affecte:發送改變的行數(UPDATE, DELETE, INSERT語句) –Bytes sent:發送多少bytes的查詢結果集 –Query size:查詢語句的字符 查詢分組統計結果 –Rank:分析的全部查詢語句的排名,默認按查詢時間降序排序 –Query ID:查詢語句的指紋 –Response time:響應時間 –Calls:查詢執行的次數 –R/Call:每次執行的平均響應時間 –V/M:響應時間Variance-to-mean的比率 –Item:查詢語句 每一個獨立查詢語句的分析
#保存到數據庫中(簡單) pt-query-digest --user=root --password=123456 --review h=127.0.0.1,D=sakila,t=global_query_review --no-report --create-review-table /var/lib/mysql/ArchLinux-slow.log #保存到數據庫中(詳細) pt-query-digest --user=root --password=123456 --history h=127.0.0.1,D=sakila,t=global_query_history --no-report --create-history-table /var/lib/mysql/ArchLinux-slow.log
2.分析數據sql
>explain select customer_id,first_name,last_name from customer; id:1 #若是id相同,從上往下順序執行;不然id值越大,優先級越高,越先執行 select_type: SIMPLE #查詢類型(簡單查詢SIMPLE;含子查詢或聯合查詢PRIAMRY;聯合查詢UNION;聯合查詢結果UNION RESULT;非from子查詢SUBQUERY;from子查詢DERIVED) table: customer #顯示這條數據是哪一張表(表的別名;derived子查詢;null計算結果) type: ALL #顯示鏈接使用何種類型(null不用訪問表或索引>const直接獲取(主索引)>eq_ref主索引引用(經常使用於多表鏈接)> ref次索引檢索>range只檢索給定範圍索引>index遍歷索引>all遍歷全表) possible_keys: NULL #顯示可能應用在這張表的索引 key: NULL #實際使用的索引 key_len: NULL #使用索引的長度(越短越好) ref: NULL #顯示索引的那一列被使用 rows: 599 #檢索行數 Extra: #額外信息(Using index:使用索引;Using where:在使用索引的基礎上進行條件判斷; Using filesort:表示MySQL須要使用臨時表來存儲結果集,常見於排序和分組查詢; Using temporary:MySQL中沒法利用索引完成的排序操做稱爲「文件排序」)
3.查詢優化數據庫
#優化Max >explain select max(payment_date) from payment; (type爲ALL) >create index idx_paydate on payment(payment_date); >explain select max(payment_date) from payment; (type爲NULL)
#優化子查詢 >explain select title,release_year,length from film where film_id in (select film_id from film_actor where actor_id in ( select actor_id from actor where first_name ='sandra') ); (採用子查詢) >explain select film.title,film.release_year,film.length from film,film_actor,actor where actor.first_name='sandra' and film_actor.actor_id=actor.actor_id and film_actor.film_id=film.film_id; (採用鏈接查詢)
#去除重複索引(重複索引指相同的列以相同的順序創建的同類型的索引) create table test( id int primary key, name varchar(10), constraint union_key unique(id) ); pt-duplicate-key-checker -u root -p '123456' -h 127.0.0.1
#去除冗餘索引(冗餘索引指多個索引的前綴列相同,或是在聯合索引中包含主鍵的索引) create table test( id int primary key, name varchar(10), index union_index(id,name(4)) ) pt-duplicate-key-checker -u root -p '123456' -h 127.0.0.1
#刪除不用的索引 pt-index-usage -u root -p '123456' -h 127.0.0.1
#索引左前綴原則【假若有聯合索引index(c1,c2,c3,c4)】 (a).where c1=x and c2=x and c4>x and c3=x : index(c1,c2,c3,c4),where添加能夠交換位置 (b).where c1=x and c2=x and c4=x order(group) by c3 : index(c1,c2,c3), (c).where c1=x and c2=x and c3=x order(group) by c4 : index(c1,c2,c3,c4) (d).where c1=x and c4=x order(group) by c2,c3 : index(c1,c2,c3),order(group) by不能夠交換位置 (e).where c1=x and c4=x order(group) by c3,c2 : index(c1)
#索引覆蓋【假如主鍵key(c1),聯合索引index(c1,c2)】 (a).select * from t1 order by c1 : key(c1), (b).select * from t1 order by c1,c2 : index(1,2)
4.如何創建索引併發
a.在where從句,group by從句,order by從句,on從句中出現的列
b.索引字段越小越好
c.離散度大的列放到聯合索引的前面(count(distinct 字段名)越大的離散度越大)