MySQL性能調優思路

1.MySQL性能調優思路

若是一臺服務器出現長時間負載太高 /週期性負載過大,或偶爾卡住如何來處理?mysql

是週期性的變化仍是偶爾問題?是服務器總體性能的問題, 仍是某單條語句的問題?sql

具體到單條語句, 這條語句是在等待上花的時間,仍是查詢上花的時間?緩存

1.1. 監測並觀察服務器的狀態.

觀察服務器狀態, 通常用以下2個命令bash

Show status;

Show processlist;

: mysql> show status;服務器

   #mysqladmin ext性能

1.2. MySQL的每秒請求數週期性變化,隨着緩存失效,有短期的高峯

解決辦法:優化

1: 減小無關請求(業務邏輯層面,暫不討論,但實際上是最有效的手段)spa

2: 若是請求數是必定的,不可減小的. 咱們要儘可能讓請求數平穩,不要有劇烈波動.code

不少時候,不是服務器撐不住總的查詢量,而是在某個時間段撐不住高峯請求.blog

1.3.對於不規則的延遲現象的觀察

不規則的延遲現象每每是因爲效率低下的語句形成的,如何抓到這些效率低的語句.

能夠用show processlist命令長期觀察,或用慢查詢.

Show processlist;

這個命令是顯示當前全部鏈接的工做狀態.

#!/bin/bash

while true

do

mysql -uroot -e 'show processlist\G'|grep State:|uniq -c|sort -rn

echo '---'

sleep 1

Done

若是觀察到如下狀態,則須要注意

converting HEAP to MyISAM     查詢結果太大時,把結果放在磁盤 (語句寫的很差,取數據太多)

create tmp table                         建立臨時表(group時儲存中間結果,說明索引建的很差)

Copying to tmp table on disk   把內存臨時表複製到磁盤 (索引很差,表字段選的很差)

locked                                         被其餘查詢鎖住 (通常在使用事務時易發生,互聯網應用不常發生)

logging slow query                   記錄慢查詢

1.4. mysql 5.5 之後加了一個profile設置,能夠觀察到具體語句的執行步驟.

查看profile是否開啓

 

Show  variables like ‘profiling’

 開啓profile

 set profiling=on;

查看profiles;

show profiles;

查看profile;

show profile for query 1;

2. 如何定位到有問題的語句?

  • 開啓服務器慢查詢
  • 瞭解臨時表的使用規則      

2.1. MySQL如何使用內部臨時表

在處理請求的某些場景中,服務器建立內部臨時表. 即表以MEMORY引擎在內存中處理,或以MyISAM引擎儲存在磁盤上處理.若是表過大,服務器可能會把內存中的臨時錶轉存在磁盤上.

用戶不能直接控制服務器內部用內存仍是磁盤存儲臨時表

2.2. 臨時表在以下幾種狀況被建立:

若是group by 的列沒有索引,必產生內部臨時表,

 

若是order by group by爲不一樣列時,或多表聯查時order by ,group by 包含的列不是第一張表的列,將會產生臨時表

 

distinct order by 一塊兒使用可能會產生臨時表

 

若是使用SQL_SMALL_RESULT,MySQL會使用內存臨時表,除非查詢中有一些必需要把臨時表創建在磁盤上.

 

union合併查詢時會用到臨時表

 

某些視圖會用到臨時表,如使用temptable方式創建,或使用union或聚合查詢的視圖

 

想肯定查詢是否須要臨時表,能夠用EXPLAIN查詢計劃,並查看Extra,看是否有Using temporary.

 

若是一開始在內存中產生的臨時表變大,會自動轉化爲磁盤臨時表. 內存中臨時表的最大值爲tmp_table_sizemax_heap_size中較小值.

這和create table時顯示指定的內存表不同:這些表只受max_heap_table_size系統參數影響.

 

當服務器建立內部臨時表(不管在內存仍是在磁盤),create_tmp_tables變量都會增長.

若是建立了在磁盤上內部臨時表(不管是初始建立仍是由in-memory轉化),

create_tmp_disk_tables 變量都會增長.

 

一些狀況下限制了內存臨時表的使用,而使用磁盤臨時表:

(使用了內部臨時表的前提下) 語句中存在BLOBTEXT

GROUP BY DISTINCT子句中有大於512字節的string

UNIONUNION ALL,SELECT語句裏有大於512字節的string.

 

建表: 表結構的拆分,如核心字段都用int,char,enum等定長結構;非核心字段,或用到text,超長的varchar,拆出來單放一張表.

建索引: 合理的索引能夠減小內部臨時表(索引優化策略裏詳解)

寫語句: 不合理的語句將致使大量數據傳輸以及內部臨時表的使用.

相關文章
相關標籤/搜索