SQL調優筆記

1. SQL性能下降原因

開始由于數據較少,SQL的執行效率不會有太大影響,但當業務數據增多時,SQL的性能會逐漸下降。SQL性能下降主要有以下4種原因

  • SQL語言寫的差【引起全表搜索,創建臨時表等】導致SQL性能下降
  • 索引失效
  • 查詢語句關聯了太多JOIN
  • 服務器參數設置存在問題【緩沖區等】

2. SQL調優

SQL調優主要分為4個步驟:

  • 慢查詢語句的捕獲
  • 使用explain分析低效語句
  • show profile分析低效語句
  • SQL數據庫服務器的調優

2.1 慢查詢的開啟和捕獲

2.1.1 查看日志開啟情況

進入mysql后,可以使用show variables like '%low_query_log%'來查看慢查詢日志開啟情況,結果會返回slow_query_log的開啟情況,一般是off,還有slow_query_log所在的位置

mysql -u root -p    # 今天mysql
# Enter password
show variables like '%slow_query_log%';

2.1.2 開啟日志

輸入set global slow_query_log = 1;開啟慢查詢日志
注意在調式時才打開慢查詢日志,平時不需要打開

set global slow_query_log = 1;  # 開啟慢查詢日志

set global slow_query_log = 0;  # 關閉慢查詢日志

2.1.3 查看和設置閾值

多慢的sql語句才會被記錄在慢查詢日志中呢?這時候就需要調整閾值,使用show variables like '%long_query_time%';可以查看當前的閾值,一般默認是10s

如果需要更小或者更大的閾值,可以使用set global long_query_time = ;來設定理想的閾值,根據實際情況設定對應閾值

show variables like '%long_query_time%';

set global long_query_time = 3;  # 設定閾值為3秒

2.1.4 查看低效SQL

在mysql中輸入 show global status like'%slow_queries%'來查看低于閾值的sql語句條數,然后根據查詢慢日志是否開啟返回的結果slow_query_log可以查看慢查詢日志文件所在位置,打開慢查詢日志查看慢于閾值的低效SQL語句

 show global status like'%slow_queries%'

慢查詢日志主要是用于低效SQL語句的捕獲,捕獲了對應的低效SQL語句后,就可以對其進行分析


2.2 使用explain分析

對于慢查詢日志捕獲的低效SQL語句,可以使用explain進行分析,分析其低效的原因
explain + SQL語句 可以查看單個SQL語句的執行計劃,模擬優化器執行SQL語句,從而知道MYSQL是如何處理MYSQL語句的,進而分析查詢語句或表結構的性能瓶頸

使用explian + SQL語句后會出現如圖所示表格,各參數意義如下:

  • id:一組數字,表示查詢中執行select子句或操作表的順序
    - d相同時,執行順序由上至下
    - d不同,id值越高,越先執行
  • select_type:查詢類型
    - SIMPLE:代表類型是簡單查詢
    - PRIMARYKEY:代表主查詢
    - UNION:UNION查詢
    - UNION:UNION返回的結果
    - SUBQUERY:子查詢
  • type:訪問類型
    - ALL:全表掃描
    -** const**:代表常量
    - eq_ref:唯一性索引掃描,只記錄一條記錄與之匹配
    - ref:代表非唯一性索引掃描,返回匹配某個單獨值得所有行
    - range:只檢索給定范圍得行,使用一個索引來選擇行
    - system:表中僅有一行

type類型從優到差的順序為system > const > eq_ref > ref > range > index > ALL
要盡量避免出現ALL,因為全表掃描嚴重影響SQL性能

  • possible_key:顯示可能應用在表中的索引,一個或多個【但不一定被查詢使用】

  • key:實際使用的索引【如果為NULL,要么沒有建立,要么索引失效】

  • key_len:表示索引中使用的字節數【同樣查詢結果得情況下,key_len越小越好】

  • ref:顯示索引的哪一列被實際使用了

  • row:根據表統計信息及索引選用情況,大致估算出找到所需得記錄所需讀取的行數【越少越好】

  • Extra:包含不適合在其他列中顯示但十分重要得額外信息
    - using filesort:文件內排序【盡量不要有using filesort】
    - using temporary:新建內部得臨時表【盡量不要生成臨時表常見于order by 和 group by】
    - using index:表明相應得select操作中使用了覆蓋索引,避免訪問了表得數據行【盡量有using index】
    - using join buffer :使用了連接緩存
    - impossible where:where子句得值總是False,不能用來獲取任何元組
    - distinct

實際使用時,主要考察,id;type;key;row;Extra。考察type中是否有ALL;key是否存在索引失效;extra是否存在using filesort和using temporary這些嚴重影響性能的情況


2.3 使用show profile分析

對比explain,使用show profile可以更進一步分析低效的SQL 語句

show profile 提供可以用來分析當前會話中語句執行的資源消耗情況,用于SQL的調優測量,默認情況下,參數處于關閉狀態

2.3.1 開啟profile

使用SHOW VARIABLES LIKE 'profiling';查看profiling開啟狀態,默認關閉,保存15條運行結果

使用SET PROFILING=on; 開啟profiling

SHOW VARIABLES LIKE 'profiling';  # 查看profiling開啟狀態

SET PROFILING=on;                  # 開啟profiling

2.3.2 分析prifile

開啟profile后,SQL語句會被記錄在profiles中,使用show profiles; 可以查看語句對應的id和運行時間

一般查看cpu占用和io情況,可以使用show profile cpu ,block io for query <id>;來查看對應id語句的cpu和io情況,也可以改為ALL查看全部信息

show profiles     # 查看profiles

show profile cpu ,block io for query 3;  # 3可以改為其他id值

2.3.3. 相關結果說明

converting HEAP to MYISAM      #查詢結果太大,內存不夠用了往磁盤上搬了
Creating tmp table             #創建臨時表
Copying to tmp table on disk ; #把內存中臨時表復制到硬盤

2.4 SQL數據庫服務器的調優

增大buffer緩沖區等方法進行數據庫服務器調優


2.5 索引分析

2.5.1 索引基本概念

  • 索引的概念:索引是幫助MYSQL高效獲取數據得數據結構,可以簡單理解為排好序得,幫助快速查找得數據結構

  • 索引優勢

    • 提高數據檢索效率,降低io成本
    • 降低數據排序的成本,降低cpu的損耗
  • 索引劣勢

    • 索引實際上是一張表,也是要占用空間
    • 會降低表的更新速度【因為要同時更新索引】
  • MYSQL索引基本語法

CREATE INDEX [indexName] ON 表明(列名)  # 創建索引

DROP INDEX [indexName] ON mytable;     # 刪除索引

SHOW INDEX FROM table_name             # 查看索引

SELECT * FROM TABLE1 FORCE INDEX (FIELD1) …    # 強制索引

SELECT * FROM TABLE1 IGNORE INDEX (idx_)…      # 忽略索引

2.5.2 索引失效

  • 在索引上執行操作時【計算、函數、類型轉換等】會導致索引失效

  • 使用不等于(!=或 <>)時無法使用索引會導致全表掃描

  • is null 和 is not null無法使用索引

  • like以通配符開頭('%abc'或‘%abc%’)會導致索引失效,導致全表掃描

  • 字符串varchar不加單引號會導致索引失效

  • 用or連接會導致索引失效

  • 使用復合索引索引了多列,沒有從最左列索引開始使用,或者跳過了索引中的前面的索引列而使用了后面的索引列【沒有使用全部索引】
    如果使用了所有索引【沒有缺失】那么sql會自動優化索引順序,即查詢的索引順序不需要和索引建立的順序一致,也不存在范圍條件右邊索引列失效的問題

  • 范圍條件右邊的索引列會失效

    • 例如:where age > 25 and pos='manager';,則pos上的索引會失效

2.5.3 索引優化

SQL索引失效主要是由于上述8種情況,除了注意避免以上情況導致的索引失效外,還要注意在建立索引上的優化

在建立索引時,要注意以下幾種問題:

  • 索引最好設置在經常查詢的字段中
  • 使用LEFT JOIN 和RIGHT JOIN 時方向要和索引相反
    - LEFT JOIN主要受右表得影響,因此使用時,index要在右表
    - RIGHT JOIN 主要受左表得影響,因此使用時,index要在左表
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,514評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,373評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,743評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,199評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,414評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,951評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,780評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,218評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,673評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374