Mysql優化、調優詳解

有用麻煩點個贊哦

1、mysql優化分析流程

1、慢查詢的開啓並捕獲運行一段時間(至少一天),查看生產慢sql的情況,開啓慢查詢日誌,設置閾值,例如超過5秒就是慢日誌,抓去出來分析
2、explain + 慢sql進行分析(基本完成大多分析)
3、show profile(更猛)查詢sql在mysql服務器裏面執行的細節和聲明週期
4、SQL數據庫服務器的參數調優(DBA或運維)


2、索引優化分析

2.1、關於索引

簡單瞭解:排好序的快速查找的數據結構除數據本身以外數據庫還維護着滿足特定查找算法的數據結構,實現查找算法。但一般來說索引本身也很大,不可能全部儲存在內存中。因此索引往往以索引文件的形式儲存在磁盤上默認索引都是指B樹其中聚集、次要、覆蓋、全文、符合、前綴、唯一索引都是默認使用B+樹,除了B+樹以外還有哈希索引。
索引失效:頻繁改動的數據不適合作爲索引,每次更新要重新改索引索引優勢提高檢索效率降低io成本通過索引列進行排序,降低排序的成本,降低cpu的消耗劣勢佔用空間降低更新表的速度
索引分類:單列索引 一個索引只包含單個列,一個表可以有多個單列索引唯一索引 索引列必須唯一但是允許空值

2.2、性能分析

mysql常見瓶頸 cpu在飽和的時候一般發生在數據裝入內存或從磁盤上讀取數據時候。
1. IO:磁盤I/O瓶頸發生在裝入數據遠大於內存容量的時候
2. 服務器硬件的性能瓶頸:top,free,iostat和vmstat來查看系統性能狀態

MySql Query Optimizer mysql自帶的分析器
Explain進行分析 :下面重點講解

2.3、Explain的使用

2.3.1 作用:

對sql語句進行優化使用方法:explain + sql語句,根據顯示的表進行優化

2.3.2通過Explain瞭解系信息:

1、表的讀取順序
2、數據讀取操作的操作類型
3、哪些索引可以被使用
4、哪些索引實際被使用
5、表之間的引用
6、每張表有多少行被優化器查詢 返回字段解釋id 表示查詢中執行select子句或操作表的順序

2.3.3 Explain 表字段(部分)

id id相同視爲同一組從上往下執行、所有組中id越大優先級越高,越先執行
select_type 查詢類型simple primary(任何複雜查詢,外層的嵌套查詢 )
union,union Result 從union表獲取結果的select
possible_keys 指出 mysql 在查詢中可能會使用的索引,但不一定會使用,mysql 會根據統計信息選出代價最小的索引
key 真實使用的索引
ref r用來與 key 中所選索引列比較的常量 (const) 或者連接查詢列(顯示爲該列名字)
rows 找到所需的紀錄需要掃描多少行
extra mysql 認爲很關鍵,但是又不應該出現在前面所述字段的信息


2.3.4 根據Explain進行索引sql優化

1、全值匹配
索引爲(a,b,c),匹配條件:where a=1 and b=2 and c=3 此時效率最佳,完美匹配索引
2、最佳左前綴法則
如果索引了多列,要遵守最左前綴法則,指的是查詢從索引的最左前列開始並且不跳過中間的索引列
3、不在索引上做任何操作
計算,函數,(自動、手動)類型轉換,會導致索引失效
4、產生全局掃描存儲引擎不能使用索引範圍條件的右邊的列建
例子:三級索引(a,b,c)時,select where a(= 什麼) and b > 什麼 order by c會導致索引失效 因爲b是一個範圍值,優化:建立索引爲(a,c)儘量使用覆蓋索引,減少用select *
5、MySQL在不使用不等於時無法使用索引
a != b 以及 a <> b 都會
6、is null,is not null 無法使用索引
創建表時,空值最好設定一個默認值,避免出現索引失效)
7、like以通配符開頭會使索引失效
(%abc這個會)(abc%這個不會),mysql索引失效會變成全表掃描的操作,
面試問題:
如何結局like"%字符串%"時索引不被使用時,用覆蓋索引解決:比如查的字段爲id,name(或者兩者其一),可以以(id,name)爲組合索引,產生覆蓋索引,此時Key字段爲該組合索引,表明索引並沒有失效
8、字符串不加單引號索引失效
如varchar類型 不加單引號,(where id=‘1’)寫成了(where id = 1),產生了隱含的類型轉換
9、少用or
用它連接時索引失效面試要點索引爲(a,b,c,d)的複合索引

2.3.5關於索引進行實例分析

1、查詢時where a = 1and b = 2 and c =3 and d =4 與where d = 4and b = 2 and c =3 and a =1 邏輯相同(Mysql 會自己調整成前者)
2、查詢時where a = 1and b = 2 and c >3 and d =4 與where a = 1and b = 2 and d>4 and c =3 不同(因爲索引順序爲abcd,所以Mysql 會自己調整爲where a = 1and b = 2 and c =3 and d>4)索引長度不同,但索引類型同樣爲range
3、where a = 1and b = 2 and d =4 order by c ;用到了ab查找,c排序explain 返回 ref爲2 ,不會把c統計進去
4、where a = 1and b = 2 order by c ;情況與3一樣,不會因爲d的是否使用而改變(因爲範圍查找右邊無法使用索引)
5、 where a = 1and b = 2 order by d;extra 產生 filesoft,因爲第三索引的c沒了,ref爲2(使用了ab索引查找)
6、where a=1 and e=5 order by b,c; ref爲const,(bc用於排序所以不會有filesoft)
7、where a=1 and e=5 order by c,b;ref爲const,但會產生using filesoft,orderby的 順序顛倒了;
8、where a=1 and b =2 order by b,c;ref爲const,const。(ab)
9、where a=1 and b =2 and e=5 order by b,c; ref爲const,const。(ab)
10、where a=1 and b =2 and e=5 order by c,b;其實和8一樣,ref爲const,const。(ab) 因爲索引b已用於查找,所以order中的c可以直接使用,順序顛倒不影響;
11、where a=1 and d=4 group by b,c;ref 爲const 只調用了a查找
12、where a=1 and d=4 group by c,b;ref 爲const 只調用了a查找,並且出現了using filesort和using temporary(group by 分組之前必定要排序,如果順序錯亂,會產生臨時表)
13、where a=1 and b like"%字符串" and c=3; ref爲 const,索引用到了a
14、where a=1 and b like"字符串%" and c=3;ref爲 const,const,const。索引用到了abc
15、where a=1 and b like"%字符串%" and c=3;ref爲 const,索引用到了a
16、where a=1 and b like"字符串%字符串%" and c=3;ref爲 const,const,const。索引用到了abc

2.3.6索引建議:

1、單鍵索引,儘量選擇針對當前query過濾性更好的索引
2、組合索引時,query過濾性更好的字段在索引字段的左邊
3、組合索引時儘量選擇可以包含當且query中的where字句中更多的字段
4、儘可能通過分析統計信息和調整query的寫法來達到選擇適合索引的目的

3、查詢截取分析

3.1查詢優化

小表驅動大表
mysql 都是使用(Nested Loop )循環套嵌的方式實現 join,耗時間比較多的是數據庫的鏈接與釋放。
以for循環爲例
for(i=0;i<1000;i++){ for(j =0 ; j<5;j++ )}
遠不如
for(i=0;i<5;i++){ for(j =0 ; j<1000;j++ )}
應用
exists和in不同,小表驅動大表原則
exists 理解爲主查詢的句子放到子查詢中做驗證,只返回true 和false。
select * from A where id in (select id in B)等價於

for select id from B    
	for select * from A where A.id =B.id

B表數據小於A表用in
select * from A where id exists(select 1 from B where in B.id = A.id)等價於

 for select id from A    
	for select * from A where A.id =B.id

B表數據大於A表用exists


3.2 雙路排序和單路排序

3.2.1 簡介

I/O是相當耗時的,Mysql 4.1版本以前使用雙路排序。兩次掃描磁盤1、先掃描並排序再掃描搜索需要的內容。4.1後單路排序orderby 在sort_buffer對數據進行排序,然後用列表進行輸出,效率更快,隨機IO變成順序IO。但是犧牲了更多的空間,每一行數據都保存在內存單路排序。

3.2.2單路排序存在問題

如果取出的數據總體大小超出了sort_buffer的容量,導致每次只能去sort_buffer的容量大小的數據,進行排序,從而多次I/O得不償失。
解決:提高OrderBy速度:
1、不用select *。只有字段大小總和小於max_length_for_sort_data且字段不是TEXT|BLOB類型時,會用改進後的算法單路排序,否則還是會用雙路服務器參數調優
2、增大sort_buffer_size參數的設置
3、增大max_length_for_sort_data的參數設置,但過高會使數據總容量超過sort_buffer_size的概率增大。爲排序使用索引

3.2.3其他

1、mysql兩種排序方式:文件排序或掃描有序索引排序
2、mysql能爲排序和查詢使用相同索引order by 要麼一起升序要麼一起降序group by其實與order by差不多,只多了一個having(能使用where的就不使用having)

3.3慢查詢日誌

3.3.1定義

慢查詢日誌設定一個閾值long_query_time,sql具體運行時間超過(=不算在內)這個閾值就會被記錄到慢查詢日誌中 默認情況下mysql沒有開啓慢查詢,除非調優需要一般不建議啓動,會降低性能。

3.3.2 啓動方式

1、臨時單個數據庫啓動(mysql重啓後會失效)set 數據庫名 slow_query_log=1set 數據庫名 long_query_time=時間閾值重開窗口即可;
2、永久啓動修改my.cnf配置文件slow_query_log=1slow_query_log_file=儲存到的文件名(不指定也會默認配置)long_query_time=時間閾值long_output=FILE重開窗口即可

3.3.3 日誌分析工具mysqldumpslow

用法
手動分析日誌是效率太低引出mysqldumpslow可以查詢前幾條數據着重分析日誌分析工具
參數表:-help 查看幫助-s 排序方式 c 訪問次數 l 鎖定時間 r 返回記錄 t 查詢時間 al 平均鎖定時間 ar 平均返回記錄 at 平均查詢時間-t 即返回前面多少條的數據-g 後面搭配正則表達式,大小寫不敏感 。

3.4 Show Profiles

介紹
mysql用於分析當前會話中語句執行的資源消耗情況,可以用於sql的調優測量,默認保存最近的15次運行結果
使用
1、show profiles;查看運行時間和sql語句
2、show profile cpu,block_io(這兩個參數相對常用) for query 想要查看的sql id號(上一條語句顯示的表裏有)
如何判斷返回的數據存在的問題?
1、converting HEAP to MyISAM 查詢結果太大,內存不夠用了
2、Creating tem table創建臨時表
3、Copying to tmp table on disk 把內存中的臨時表複製到內存
4、locked

3.5 全局查詢日誌

只允許在測試環境用,比較推薦功能更爲搶答的show profile;

有用麻煩點個贊哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章