MySQL高級(索引優化+慢查詢定位)

1、先談談事務

1. ACID特性

1.1 原子性: 事務是最小的執行單位,不容許分割。事務的原子性確保動做要麼所有完成,要麼徹底不起做用;
1.2 一致性: 執行事務先後,數據庫從一個一致性狀態轉換到另外一個一致性狀態。
1.3 隔離性: 併發訪問數據庫時,一個用戶的事物不被其餘事務所幹擾,各併發事務之間數據庫是獨立的;
1.4 持久性: 一個事務被提交以後。它對數據庫中數據的改變是持久的,即便數據庫 發生故障也不該該對其有任何影響。mysql

2. 事務隔離級別

2.1 READ_UNCOMMITTED(未提交讀): 最低的隔離級別,容許讀取還沒有提交的數據變動,可能會致使髒讀、幻讀或不可重複讀
2.2 READ_COMMITTED(提交讀): 容許讀取併發事務已經提交的數據,能夠阻止髒讀,可是幻讀或不可重複讀仍有可能發生
2.3 REPEATABLE_READ(可重複讀): 對同一字段的屢次讀取結果都是一致的,除非數據是被自己事務本身所修改,能夠阻止髒讀和不可重複讀,但幻讀仍有可能發生。
2.4 SERIALIZABLE(串行): 最高的隔離級別,徹底服從ACID的隔離級別。全部的事務依次逐個執行,這樣事務之間就徹底不可能產生干擾,也就是說,該級別能夠防止髒讀、不可重複讀以及幻讀。可是這將嚴重影響程序的性能。一般狀況下也不會用到該級別。sql

Mysql 默認採用的 REPEATABLE_READ隔離級別

2、瞭解索引

1. 什麼是索引

索引是一種幫助MySQL高效獲取數據的數據結構

2. 優點和劣勢

優點:數據庫

  1. 提升數據檢索的效率,下降數據庫的IO成本
  2. 下降數據排序的成本,下降了CPU的消耗

劣勢:數據結構

  1. 索引列要佔用空間
  2. 下降了更新表的速度(INSERT、UPDATE)
  3. 創建優秀索引的時間成本

3. 哪些狀況須要建立索引

  • 主鍵自動創建惟一索引
  • 頻繁做爲查詢條件的字段應該建立索引
  • 查詢中與其餘表關聯的字段,外鍵關係創建索引
  • where條件裏用不到的字段不建立索引
  • 單鍵/組合索引的選擇問題,在高併發傾向建立組合索引
  • 查詢中排序的字段,排序字段若經過索引去訪問將大大提升排序速度
  • 查詢中統計或分組字段

4. 哪些狀況下不須要建立索引

  • 表記錄太少
  • 頻繁更新的字段不適合建立索引,由於每次更新不僅僅是更新了記錄還會更新索引,加劇了IO負擔
  • 數據重複且分佈平均的表字段(若某個數據列包含許多重複的內容,爲它創建索引就沒有太大的實際效果,即過濾性很差的字段)

3、EXPLAIN【重點】

使用EXPLAIN關鍵字能夠模擬優化器執行SQL查詢語句, 從而知道MYSQL是如何處理你的SQL語句的,分析你的查詢語句或是表結構的性能瓶頸

EXPLAIN查詢出來的字段

a、id併發

①id相同,執行順序由上至下函數

②id不一樣,id值越大優先級越高,越先被執行高併發

b、select_type性能

查詢的類型,主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢

c、table優化

顯示這行的數據是關於哪張表的。

d、type(最好到最差的順序)spa

  • system:表只有一行記錄(等於系統表),這是const的特例,平時不會出現,這個能夠忽略
  • const:表示經過索引一次就找到了,const用於比較primary key或者unique索引。由於只匹配一行數據,因此很快。如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量
  • eq_ref:惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配。經常使用於主鍵或惟一索引掃描
  • ref:非惟一性索引掃描,返回匹配某個單獨值的全部行,可能會找到多個符合符合條件的行
  • range:只檢索給定範圍的行,使用一個索引來選擇行。key列顯示使用了哪一個索引。通常是你的where語句中出現between、<、>、in等的查詢,這種範圍掃描索引掃描比全表掃描要好
  • index:index與all的區別爲index類型只遍歷索引樹,也就是說,雖然all和index都是讀全表,但index是從索引中讀取的,而all是從硬盤中讀取的
  • all:遍歷全表
備註:通常來講,得保證查詢至少達到range級別,最好能達到ref

e、possible_keys

可能應用到這張表的索引

f、key

實際使用的索引

g、key_len

索引使用的字節數,在不損失精確性的狀況下,長度越短越好

h、ref

顯示索引的哪一列被使用了

i、rows

大體估算出找到所需記錄所須要讀取的行數

j、Extra

  • Using filesort:說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中沒法利用索引完成的排序操做稱爲「文件排序」
  • Using temporary:使用了臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表,常見於排序order by和分組查詢group by
  • USING index:表示相應的select操做中使用了覆蓋索引,避免訪問了表的數據行

什麼狀況下索引會失效

  • 全值匹配
  • 最佳左前綴法則
  • 不在索引列上作任何操做(計算、函數、(手動或自動)類型轉換),會致使索引失效而轉向全表掃描
  • 存儲引擎不能使用索引中範圍條件右邊的列
  • 儘可能使用覆蓋索引
  • MySQL在使用不等於(!=或<>)的時候沒法使用索引會致使全表掃描
  • is null,is not null也沒法使用索引
  • like以通配符開頭(「%abc..‘)MySQL索引失效會變成全表掃描的操做
  • 字符串不加單引號索引失效(自動類型轉換)
  • or左邊有索引、右邊沒索引也會失效

order by關鍵字優化

  • 儘可能使用index方式排序,避免使用filesort方式。
  • order by知足兩種狀況會使用index排序:①、order by語句使用索引最左前列,②、使用where子句與order by子句條件列組合知足索引最左前列
  • 雙路排序:MySQL4.1以前,兩次掃描磁盤
  • 單路排序:從磁盤讀取查詢須要的全部列,按照order by列在buffer對它們進行排序,而後掃描排序後的列進行輸出,效率更高一點,可是它會使用更多的空間,由於它把每一行都保存在內存中了
優化策略: 增大sort_buffer_size參數的設置、增大max_length_for_sort_data參數的設置

group by關鍵字優化

實質是先排序後進行分組,遵守索引鍵的最佳左前綴,當沒法使用索引列時,增大sort_buffer_size+max_length_for_sort_data參數的設置

3、慢查詢【重點】

1. 慢查詢日誌是什麼

MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。

具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。long_query_time的默認值爲10,意思是運行10秒以上的語句。

由他來查看哪些SQL超出了咱們的最大忍耐時間值,好比一條sql執行超過5秒鐘,咱們就算慢SQL,但願能收集超過5秒的sql,結合以前explain進行全面分析。

2. 怎麼用

默認狀況下,MySQL數據庫沒有開啓慢查詢日誌,須要咱們手動來設置這個參數。(固然,若是不是調優須要的話,通常不建議啓動該參數,由於開啓慢查詢日誌會或多或少帶來必定的性能影響。慢查詢日誌支持將日誌記錄寫入文件。)
-- 查看開啓狀況
SHOW VARIABLES LIKE '%slow_query_log%';

-- 開啓(只對當前數據庫生效,若是要永久生效,就必須修改配置文件my.cnf)
set global slow_query_log=1;

3. Show Profile【重點】

3.1. 是什麼
mysql提供能夠用來分析當前會話中語句執行的資源消耗狀況。能夠用於SQL的調優的測量,相比explain,show profile展現的數據更加詳盡。
3.2. 怎麼用
-- 查看是否開啓
show variables like 'profiling';

-- 開啓功能,默認是關閉,使用前須要開啓
set profiling=1;

-- 查看結果
show profiles;

-- 診斷SQL
show profile cpu,block io for query n;
-- 還能夠經過SELECT * FROM information_schema.profiling WHERE query_id = n ORDER BY seq;獲取

clipboard.png

相關文章
相關標籤/搜索