1. 程式人生 > >常見SQL優化手段

常見SQL優化手段

慢SQL優化手段總結

  • MySQL支援配置指定記錄慢查的資訊。

SHOW VARIABLES LIKE 'slow%’可以去顯示DB當前慢查的配置。
slow_launch_time表示建立執行緒花費超過這個閥值,slow_launch_threads計數增加。

slow_query_log是顯示慢查日誌是否開啟。

slow_query_log_file:日誌儲存路徑。

Long_query_time:SQL執行達到多少秒就記錄日誌。

SHOW VARIABLES LIKE ‘long%’
客戶端可以set開啟滿查詢也可以,但是重啟和修改配置檔案就失效了。

My.cnf:
  slow_query_log=ON
  slow_query_log_file=/var/lib/mysql/localhost-centos-slow.log
  long_query_time=3

重啟MySQL就能在指定日誌看到超過3秒的慢SQL記錄。

  • EXPLAIN命令

加在SELECT 語句前面,能看到執行計劃。

  • Id:

     JOIN和子查詢(老版本貌似不支援)代表執行順序,id越大越先執行。
    
  • select_type:

     Simple: 不使用表連線
     union union後的查詢
     Subquery 子查詢
     Derived 派生表
    
  • Type

     代表查詢資料的方式,按照查詢效能從差到好的排序
     all 全表掃描,效能很差,一般可以加索引
     Index 索引全掃描,遍歷索引查詢匹配的行
     Range 索引範圍掃描,<  > between等操作
     Ref 使用一索引的字首掃描,返回單行
     eq_ref 使用唯一索引掃描
     Const/system 單表最多匹配一個,pk或則uk查詢
     Null   MySQL不用訪問表,直接返回結果
    
  • possible_keys

     查詢可能使用的索引
    
  • Key:

     實際使用的索引
    
  • key_len:

     使用索引欄位的長度
    
  • Rows:

     掃描數量
    
  • Extra:

     額外的執行資訊
    
  • Using index :

     直接訪問索引能夠取到資料,高效能表現
    
  • Using where :

     	直接主鍵索引過濾資料,必帶where,用不上索引
     	…
    

  • 一些SQL語句優化
  1. COUNT語句
    COUNT()與COUNT(某個欄位)的區別是COUNT(某個欄位)統計欄位非NULL的行數。
    COUNT(1)與COUNT(
    )都是統計primary Key,效率一樣,如果沒有PK,全表掃描.
    如果COUNT(column) ,其中column為索引,COUNT(column)和COUNT(1)一樣快,否則COUNT(column)走全表掃描。

  2. ORDER BY 語句
    有序索引extra 顯示Using Index的話,MySQL有序返回,效率非常高。
    返回資料排序,Using file sort,使用排序演算法在sort_buffer_size系統變數設定的記憶體排序區中進行排序,記憶體裝不下在磁碟,然後合併結果。file sort優化,減少額外排序,建立合適索引,select * 改成指定的欄位,減少排序區的使用。

  3. GROUP BY語句
    GROUP BY預設加了ORDER BY ,不用再加ORDER BY
    GROUP BY如果不關係排序,可以 ORDER BY NULL 禁止排序降低排序消耗。

  4. LIMIT 語句
    指定的範圍小可以先拿出key值再去查全部欄位, 避免查太多資料。
    SELECT * FROM basic_warehouse bw INNER JOIN (SELECT id FROM basic_warehouse LIMIT 10,20) t ON t.id= bw.id
    或則標記分頁開始位置:
    SELECT * FROM basic_warehouse WHERE id > 100 LIMIT 10

  5. 子查詢
    一般來說JOIN 比子查詢效率高

  6. 執行索引優先順序
    指定走索引 SELECT * FROM basic_warehouse USE INDEX(name) 走索引複雜的IO的成本太高可能直接走全表掃描
    評估後可以強制走索引SELECT * FROM basic_warehouse FORECE INDEX(name)
    如果IO效率太低,可以讓MySQL忽略一個索引,SELECT * FROM basic_warehouse IGNORE INDEX(name)

  7. 避免全表掃描
    使用NULL值判斷會放棄索引走全表:WHERE name IS NULL。如果是char,建欄位就固定,是不是null都會佔100字元。varcher null不佔空間
    設定預設值=0比欄位 IS NULL搜尋好。
    使用!= 或則<>會導致掃描全表
    Where a = 1 OR b = 2,不是兩個欄位都有索引的情況下,掃全表. 可以使用SELECT * FROM table WHERE a = 1 UNION ALL SELECT * FROM table WHERE b = 2
    IN 和 NOT IN 都會掃全表, 很多時候可以用exits代替。
    LIKE 模糊查詢全表掃描
    WHERE 中有表示式操作會全表掃描。例如WHERE a - 1 = 10,改成 a= 11
    WHERE 有函式表示式會掃描全表