天天看點

性能測試之慢sql分析優化

作者:lT點工小橙子

#頭條創作挑戰賽#

慢sql分析

查詢生成慢sql的位置,通過指令複制到docker容器外

docker cp centos7_mysql57:/var/lib/mysql/e2d0077fb342-slow.log $PWD

性能測試之慢sql分析優化

打開檔案,複制sql到Navicat執行

性能測試之慢sql分析優化

查詢耗時20s

性能測試之慢sql分析優化

使用 explain 分析sql執行過程

  • 表的讀取順序
  • 資料讀取操作的操作類型
  • 哪些索引可以使用
  • 哪些索引被實際使用
  • 表之間的引用
  • 每張表有多少行被優化器查詢
性能測試之慢sql分析優化

rows表示掃描的行數

explain表字段的含義:

  • id: 編号
  • select_type: 查詢類型
  • table: 表
  • type: 類型
  • possible_keys: 預測用到的索引
  • key: 實際用到的索引
  • key_len: 使用的索引長度
  • ref: 表之間的比對條件
  • rows:查找到記錄所掃描的行數
  • extra: 額外的 在這個裡面會告訴你,我們腳本是否有使用條件
EXPLAIN SELECT EXPLAIN SELECT
ca.id,ca.username,ca.gqid
FROM
cb_account ca
WHERE id
IN
(SELECT DISTINCT(user_id) from cb_order co);           
性能測試之慢sql分析優化

在id相同時,sql執行的執行過程:從上往下執行,子查詢先執行

select_type: 查詢類型 - 枚舉含義

  • PRIMARY:查詢中包含複雜的子查詢,最外層的select被标記為PRIMARY
  • SUBQUERY:子查詢的第一個select
  • SIMPLE:簡單的SELECT,不使用union或子查詢
  • UNION:union中第二個或後面的select語句
  • DEPENDENT UNION: union中的第二個或後面的select語句,取決于外面的查詢
  • UNION RESULT: union的結果
  • DEPENDENT SUBQUERY:子查詢中的第一個select,取決于外面的查詢
  • DERIVED:衍生查詢,使用了臨時表(select、from子句的子查詢)
  • UNCACHEABLE SUBQUERY: 一個子查詢的結果不能被緩存,必須重新評估外連結的第一行

type: 類型 - 枚舉含義

system ,const:MySQL對查詢某部分進行優化,并轉換為一個常量時,使用這些類型訪 問。如将主鍵置于where清單中,MySQL就能将該查詢轉換為一個常量,system是const類型的特例,當查詢的表隻有一行的情況下,使用system

eq_ref:類似ref,隻是使用的索引為唯一索引

ref:使用了索引列上值進行查詢

range:使用一個索引來檢索給定範圍的行

index:索引 周遊索引資料Full index scan

ALL : 全表掃描,你要找資料,要全表查找 影響性能

NULL: MySQL在優化過程中分解語句,執行時甚至不用通路表或索引

性能效率排行 system > const > eq_ref > ref > range > index > all

extra 類型 - 枚舉含義

  • using where:顯示的字段,不在索引
  • Using index: 使用了索引,不 用回表查詢,能夠起到性能提升
  • Using temporary: 使用了臨時表,消耗比較大,常見于group by語句
  • Using filesort:使用檔案排序,無法利用索引完成排序操作,性能消耗非常大
  • Using join buffer:mysql引擎使用了連接配接緩存
  • Impossible where: where 子句永遠為false
  • Select tables optimized away:僅通過使用索引,優化器可能僅從聚合函數結果中傳回一行

優化慢 sql

性能測試之慢sql分析優化

type:ALL 表示為全表掃描

rows:查找了14w的資料

key 為空說明沒有使用索引

優化點:建立mobile的索引

性能測試之慢sql分析優化

建立索引

使用索引後,查詢時間由20s優化到0.3s

性能測試之慢sql分析優化

SQL優化方法

  • 寫on語句時,将資料量小的表放左邊,小表寫左邊,大表寫右邊
  • where後面的條件盡可能用索引字段,複合索引時,最好按複合索引順序寫where條件
  • where後面有in語句,in字段的索引,最好放複合索引的後面,因為in的字段索引可能會失效
性能測試之慢sql分析優化
  • 模糊查詢時,盡量用常量開頭,不要用%開頭,用%開頭查詢索引将失效
  • 減少不要使用or,否則索引失效
  • 減少使用類型轉換(顯式、隐式),因其會導緻索引失效
  • 如果主查詢資料量大,則使用in,如果子查詢資料量大,則使用exists查詢哪些列
  • 查詢那些列,就根據哪些列group by,不然會産生一個臨時表