mysql資料庫健康診斷 MySQL 慢的診斷思路

2021-10-18 22:29:46 字數 3259 閱讀 8305

1、問題

如果遇到 mysql 慢的話,你的第一印象是什麼,mysql 資料庫如果效能不行,又該是如何處理的?

一些反饋如下:

第一反應是再試一次

第二個反應是優化一下 sql

第三個反應是調大 buffer pool,然後開始換硬體了,換一下 ssd

分析一下這些現象背後隱藏的意義:

如果再試一次能夠成功的話, 意味著你可能碰到了不可復現的外界因素的影響,導致 mysql 會慢。

如果優化 sql 能解決,就意味著 sql 的執行複雜度遠遠大於它的需求複雜度。

如果調大 buffer pool 能解決,就意味著 mysql 碰到了自身的某些限制。

如果換 ssd 能解決,那麼意味著伺服器資源受到了一定的限制。

2、mysql 慢的診斷思路

mysql 慢的診斷思路,一般會從三個方向來做:

mysql 內部的觀測

外部資源的觀測

外部需求的改造

2.1、mysql 內部觀測

常用的 mysql 內部觀測手段是這樣的:

第一步是 processlist,看一下哪個 sql 壓力不太正常;

第二步是 explain,解釋一下它的執行計畫;

第三步要做 profilling,如果這個 sql 能再執行一次的話, 就做乙個 profilling;

高階的 dba 會直接動用 performance_schema ,mysql 5.7 以後直接動用 sys_schema,sys_schema 是乙個檢視,裡面有便捷的各類資訊,幫助大家來診斷效能;

再高階一點,會動用 innodb_metrics 進行乙個對引擎的診斷。

2.2、外部資源觀測

這裡引用國外乙個大神寫的文章,標題是《60 秒的快速巡檢》。我們來看一下它在 60 秒之內對伺服器到底做了乙個什麼樣的巡檢。一共十條命令,下面一條一條來看一下。

uptime,uptime 告訴我們這個機器活了多久,以及它的平均負載是多少。

dmesg -t | tail,告訴我們系統日誌裡邊有沒有什麼報錯。

vmstat 1,告訴我們虛擬記憶體的狀態,頁的換進換出有沒有問題,swap 有沒有使用。

mpstat -p all 1,告訴我們 cpu 壓力在各個核上是不是均勻的。

pidstat 1,告訴我們各個程序的對資源的占用大概是什麼樣子。

iostat-xz 1,檢視 io 的問題。

free-m 記憶體使用率;

sar-n dve 1,

sar-n tcp, etcp 1,8 和 9 兩條按裝置網絡卡裝置的維度,看一下網路的消耗狀態,以及總體看 tcp 的使用率和錯誤率是多少。

top,看一下大概的程序和執行緒的問題。

這個就是對於外部資源的診斷,這十條命令揭示了應該去診斷哪些外部資源。

2.3、外部需求改造

第三個診斷思路是外部的需求改造,在這裡引用了 mysql 官方文件中的一章,《examples of common queries 》( 文件中介紹了常規的 sql 怎麼寫, 給出了一些例子。

下面看一下它其中提到的乙個例子。

sql指令碼:

create table shop (

article int(4) unsigned zerofill default '0000' not null,

dealer char(20) default '' not null,

price double(16,2) default '0.00' not null,

primary key(article, dealer));

insert into shop values

(1,'a',3.45),(1,'b',3.99),(2,'a',10.99),(3,'b',1.45),

(3,'c',1.69),(3,'d',1.25),(4,'d',19.95);

執行結果;

shop表

需求:從這個表裡選取每個作者最貴的商品列在結果集中

sql語句:

select article, dealer, price

from shop s1

where price=(select max(s2.price)

from shop s2

where s1.article = s2.article);

執行結果:

最貴商品結果集

這是它最原始的 sql,非常符合業務的寫法,但是它是個關聯子查詢。 關聯子查詢成本是很貴的,所以上面的文件會教你快速地把它轉成乙個非關聯子查詢。

改造sql語句:

select s1.article, dealer, s1.price

from shop s1

join (

select article, max(price) as price

from shop

group by article) as s2

on s1.article = s2.article and s1.price = s2.price;

大家可以看到中間的子查詢和外邊的查詢之間是沒有關聯性的。

改造後的執行結果:

最貴商品結果集

最後,會教大家直接把子查詢拿掉,然後轉成這樣乙個 sql,這個就叫業務改造,前後三個 sql 的成本都不一樣,把關聯子查詢拆掉的成本,拆掉以後 sql 會跑得非常好,但這個 sql 已經不能良好表義了,只有在診斷到 sql 成本比較高的情況下才建議大家使用這種方式。

改造sql語句

select s1.article, s1.dealer, s1.price

from shop s1

left join shop s2 on s1.article = s2.article and s1.price < s2.price

where s2.article is null;

執行結果和之前一樣不在貼圖

為什麼它能夠把乙個關聯子查詢拆掉?

這背後的原理是關係代數,所有的 sql 都可以被表達成等價的關係代數式,關係代數式之間有等價關係,這個等價關係通過變換可以把關聯子查詢拆掉。

總結一下,對於 mysql 慢的診斷思路如下:

第一,mysql 本身提供了很多命令來觀察 mysql 自身的各類狀態,從上往下檢一般能檢到 sql 的問題或者伺服器的問題。

第二,從伺服器的角度,我們從巡檢的指令碼角度入手,伺服器的資源就這幾種,觀測手法也就那麼幾種,把伺服器的資源全部都觀察一圈就可以了。

第三,如果實在搞不定,需求方一定要按照資料庫容易接受的方式去寫 sql,這個成本會下降的非常快,這個是常規的 mysql 慢的診斷思路。

資料庫mysql軟體安裝 資料庫軟體mysql安裝

2.解壓至欲安裝的目錄下 3.開啟cmd,進入軟體目錄下d qmdownload mysql 5.7.24 winx64 bin,執行mysqld 4.初始化使用者 cmd d qmdownload mysql 5.7.24 winx64 bin,執行mysqld initialize insecu...

mysql資料庫之python鏈結mysql

使用之前請在命令列pip install pymysql import pymysql 1.建立鏈結 conn pymysql.connect host 127.0.0.1 ip位址 port 3306,埠號 database database name 資料庫名稱 user mysql usern...

課程表資料庫 mysql 課程表資料庫 mysql

課程表資料庫 mysql 雲伺服器 elastic compute service,簡稱ecs 是阿里雲提供的效能卓越 穩定可靠 彈性擴充套件的iaas infrastructure as a service 級別雲計算服務。雲伺服器ecs免去了您採購it硬體的前期準備,讓您像使用水 電 天然氣等公...