目的:1.避免慢查詢形成頁面沒法加載mysql
2.因爲數據庫鏈接timeout產生5xx錯誤sql
3.因爲阻塞形成數據沒法提交數據庫
慢查詢分析日誌:pt-query-digest分析前幾個查詢函數
優化當面入手:優化
硬件,系統配置,數據庫表結構,sql及索引 效果:低到高 成本: 高到低操作系統
rpm -qal | grep mysql 查找mysql字段目錄線程
ps -ef | grep mysql 查看線程號和目錄unix
cat /etc/my.conf mysql配置文件日誌
datadir是你數據文件的存放路徑排序
basedir纔是mysql軟件的安裝路徑
explain --查詢sql執行技術
key_len:使用的索引的長度,在不損失精確度狀況下,長度越短越好
ref:顯示索引的哪一列被使用,若是可能的話,是一個常數最好
type 顯示鏈接使用什麼類型,從好到差:const,eq_reg,ref,range,index,all
extra列須要注意的返回值
Using filesort: 查詢須要優化,須要額外的步驟來發現如何對返回的行排序,使用文件排序
Using temporary: 查詢須要優化 ,這裏建立臨時表進行存儲結構,一般發生在不一樣列集上的order by,而不是group by
備份
mysqldump --all-databases > all-databases.sql(將全部數據庫備份到all-databases.sql文件,all-databases.sql是一個文本文件,文件名任取。)
count()和max()優化:
count(*)查詢行數
count(1)查詢不爲null的行數
max(age)->age字段創建索引 count()同理
子查詢優化:
改成鏈接join查詢(注意1對多關係)
group by優化方式:
在子查詢用group by過濾條件
例如:
優化前:explain select a.name,c.cnt from a inner join b using id group by b.id;
優化後:explain select a.name,c.cnt from a inner join(select id,count(*) from b group by id) as c using id;
limit優化方式:
limit經常使用分頁處理,時常會伴隨order by 從句使用,所以常常會形成filesort這樣的I/O問題
步驟1:使用索引的列或者主鍵進行order by操做
步驟2:藉助上一次返回的id,用id進行過濾,缺點:id自增且連續 --->避免數量亮大時掃描過多的記錄
例如:select id from a where id >55 and id<=60 order by id limit 1,5;
如何選擇合適的列創建索引?
1.在where,group by ,order by,on 從句中出現的列
2.索引字段越小越好
3.離散度大的列放在聯合索引前面
例如:select * from payment where staff_id =2 and customer_id =584;
因爲customer_id離散度更大,因此應該是(customer_id,staff_id);
如何判斷列的離散度大小 ---> select count(distinct customer_id) from payment; -->599
select count(distinct staff_id) from payment; -->2
索引優化
過多的索引會影響寫入,有時也會影響查詢
冗餘索引:多個索引的前綴列相同,或在聯合索引中包含了主鍵的索引,下面key(name,id)就是一個冗餘索引
create table test(
id int not null primay key,
name varchar(10) not null,
title varchar(50) not null,
key(name,id)
)engine=innodb
重複索引:相同的列以相同的順序創建的同類型的索引。下面primary key和id列上的索引就是重複索引
create table test(
id int not null primay key,
name varchar(10) not null,
title varchar(50) not null,
unique(id)
)engine=innodb
使用pt-duplicate-key-checker -uroot -p'' -h127.0.0.1檢查重複索引和冗餘索引
選擇的合適的數據類型
1.使用能夠存下你的數據的最小數據類型
2.使用簡單的數據類型,int要比varchar類型在mysql處理上簡單
3.儘量使用not null定義字段
4.儘可能少用text類型,非用不可時最好考慮分表
使用int來存儲日期時間,利用from_unixtime(),unix_timestamp()2個函數來進行轉換
使用bigint來存ip地址,使用inet_aton(),inet_ntoa()2個函數來替換
表的垂直拆分,水平拆分
垂直拆分:將單表按照業務拆分多個表
水平拆分:單表分紅多個相同的表,表1,表2,表3。。。。。
操做系統配置優化