它的建議是機器核數乘以 2 加 1。也就是說,4 核的機器,連接池維護 9 個連接就夠了。
這個公式從一定程度上來說對其他數據庫也是適用的。
爲什麼有的情況下,減少連接數反而會提升吞吐量呢?
爲什麼建議設置的連接池大小要跟 CPU 的核數相關呢?
每一個連接,服務端都需要創建一個線程去處理它。連接數越多,服務端創建的線程數就越多。
CPU的核數是有限的,執行多個線程,頻繁切換(線程)上下文會造成比較大的性能開銷。
不管是數據庫本身的配置,還是按照這個數據庫服務的操作系統的配置,
對配置進行優化,最終的目的都是使硬件本身的性能更好發揮,包括CPU、內存、磁盤、網絡。
在之前的內容中也接觸了很多的MySQL和InnoDB的配置參數,包括各種開關和數值的配置,
大多數參數都提供了一個默認值,比如默認的buffer_pool_size,默認的頁大小,InnoDB的併發線程數等等。
這些默認配置可以瞞住大部分情況的需求,除非有特殊的需求,在清楚參數的含義時再去修改它。
修改配置的工作一般由專業的DBA完成。
這是官網系統的參數列表,需要時再做參考:
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
除了合理設置服務端連接數和客戶端連接池大小外,還有哪些減少客戶端和數據庫服務端的連接數的方案呢?
可以引入緩存。
三、緩存——架構優化
3.1 緩存
在應用的併發數非常大的情況下,如果沒有緩存,會造成兩個問題:
一是會給數據庫帶來很大壓力,二是對於應用來說操作數據的速度也會受影響。
可以採用第三方緩存來解決這個問題,比如 Redis。
運行獨立的緩存服務,屬於架構層面的優化
爲了減少單臺數據庫服務器的讀寫壓力,在架構層面還可以做哪些其他優化措施?
還可以採取主從複製、分庫分表等方案。
四、優化器——SQL語句分析優化
優化器就是對我們的 SQL 語句進行分析,生成執行計劃。
4.1 慢查詢日誌(slow query log)
我們可以通過慢查詢日誌知道服務中哪些SQL語句比較慢。
因爲開啓慢查詢日誌是有代價的(和bin log、optimizer-trace一樣),所以默認關閉。
show variables like '%slow_query%';
除了這個開關,還有一個參數,控制執行多久的SQL才被記錄到慢日誌,默認是10秒:
show variables like '%long_query%';
可以直接動態修改參數(重啓後失效):
set @@global.slow_query_log=1; -- 慢查詢日誌開關 1 開啓,0 關閉,重啓後失效
set @@global.long_query_time=3; -- mysql 默認的慢查詢時間是 10 秒,另開一個窗口後纔會查到最新值
或者修改配置文件 my.cnf,讓配置永久生效。
以下配置定義了慢查詢日誌的開關、慢查詢的時間、慢日誌文件的存放路徑。
slow_query_log = ON
long_query_time=2
slow_query_log_file =/var/lib/mysql/localhost-slow.log
show global status like 'slow_queries'; -- 查看有多少慢查詢
show variables like '%slow_query%'; -- 獲取慢日誌目錄
雖然有了慢日誌,但是慢日誌記錄了所有超過設定值的慢查詢,如何統計分析呢?總不能一條一條數。
MySQL提供了mysqldumpslow的工具,在MySQL的bin目錄下。
例如:查詢用時最多的20條慢SQL:
mysqldumpslow -s t -t 20 -g 'select' /var/lib/mysql/localhost-slow.log
Count:代表這條SQL被執行了多少次;
Time:代表執行的時間,括號內是累計時間;
Lock:代表鎖定的時間,括號是累計鎖定時間;
Rows:代表返回的記錄數,括號是累計;
4.2 show profile
除了慢查詢日誌,還有show profile工具可以使用
https://dev.mysql.com/doc/refman/5.7/en/show-profile.html
show profile可以查看SQL語句執行的時使用的資源,比如CPU、IO的消耗情況。
查看是否開啓:
select @@profiling;
若未開啓則手動開啓:
set @@profiling=1;
查看 profile 統計
show profiles;(命令最後帶一個 s)
查看最後一個 SQL 的執行詳細信息,從中找出耗時較多的環節(沒有 s)。
show profile;
此處時間6.2E-5表示小數點左移 5 位,代表 0.000062 秒。
也可以根據 ID 查看執行詳細信息,在後面帶上 for query + ID。
show profile for query 1;
除了慢日誌和 show profile,如果要分析出當前數據庫中執行的慢的 SQL,還可以
通過查看運行線程狀態和服務器運行信息、存儲引擎信息來分析。
其他系統命令
show processlist 運行線程
show processlist;
用於顯示用戶運行線程。可以根據 id 號 kill 線程。
也可以查表,效果一樣:
select * from information_schema.processlist;
Id : 線程的唯一標誌,可以根據它 kill 線程
User : 啓動這個線程的用戶,普通用戶只能看到自己的線程
db : 操作的數據庫
show status 服務器運行狀態
SHOW STATUS 用於查看 MySQL 服務器運行狀態(重啓後會清空),有 session 和 global 兩種作用域,格式:參數-值。
可以用 like 帶通配符過濾。
SHOW GLOBAL STATUS LIKE 'com_select'; -- 查看 select 次數
show engine 存儲引擎運行信息
show engine 用來顯示存儲引擎的當前運行信息,包括事務持有的表鎖、行鎖信息;
事務的鎖等待情況;線程信號量等待;文件 IO 請求;buffer pool 統計信息。
例如:
show engine innodb status;
如果需要將監控信息輸出到錯誤信息 error log 中(15 秒鐘一次),可以開啓輸出。
show variables like 'innodb_status_output%';
-- 開啓輸出:
SET GLOBAL innodb_status_output=ON;
SET GLOBAL innodb_status_output_locks=ON;
其實很多開源的慢查詢日誌監控工具,他們的原理其實也都是讀取的系統的變量和狀態。
那麼,現在我們已經知道哪些 SQL 慢了,爲什麼慢呢?慢在哪裏?
MySQL 提供了一個執行計劃的工具,
通過 EXPLAIN 我們可以模擬優化器執行 SQL 查詢語句的過程,來知道 MySQL 是
怎麼處理一條 SQL 語句的。通過這種方式我們可以分析語句或者表的性能瓶頸。
4.3 EXPLAIN 執行計劃