是什么影響了 MySQL 的性能?
松哥有兩個小伙伴最近在幫人改造一個系統(tǒng),對方原本的系統(tǒng)是一個用 Java GUI 做的桌面應用,現(xiàn)在要用 Spring Boot 改造成一個 Web 應用。原本的應用在 Mac 上運行的時候非常絲滑,但是在 Windows 上運行的時候,就特別卡。經(jīng)過分析之后,發(fā)現(xiàn)是因為數(shù)據(jù)庫中數(shù)據(jù)量過大導致每一次的查詢都非常緩慢。
為了解決這一問題,他們特地來咨詢了松哥,我也趁此機會整理了一下數(shù)據(jù)庫優(yōu)化的基本操作,形成了幾篇文章,接下來就和小伙伴們逐一分享。
今天我們主要來看下,到底是什么影響了數(shù)據(jù)庫的性能?找到問題的原因,才能解決問題。
整體上來說,影響數(shù)據(jù)庫性能的因素,我們可以歸為以下幾個方面:
- SQL 腳本
- 數(shù)據(jù)庫服務(wù)器配置
- 網(wǎng)卡流量
- 磁盤 IO
- 大表操作
- 大事務(wù)操作
- 存儲引擎
- 數(shù)據(jù)庫參數(shù)配置
接下來我們就從這幾個方面來逐一進行說明。
1. SQL 腳本
SQL 腳本會影響到 MySQL 的執(zhí)行效率,這個大家都懂,面試八股文中常見問題之一。其實也不是面試官故意愛考這個問題,只是這個東西太重要了,根據(jù)松哥的經(jīng)驗,80% 的數(shù)據(jù)庫問題,都是由慢 SQL 導致的,都可以通過 SQL 優(yōu)化來解決,所以 SQL 優(yōu)化技能對于開發(fā)者而言就非常重要了(有條件的公司也可以聘請 DBA,但是大部分公司是沒有 DBA 的),這也是為什么我們在面試時經(jīng)常會遇到 SQL 優(yōu)化的原因。
那么慢 SQL 究竟會帶來哪些風險呢?
超高的 QPS 和 TPS
可能有人還不清楚什么是 QPS 和 TPS,因此我們這里先對這兩個做一個簡單介紹。
- TPS:英文全稱是 Transactions Per Second,即服務(wù)器每秒處理的事務(wù)數(shù)。TPS 包括一條消息入和一條消息出,加上一次用戶數(shù)據(jù)庫訪問。這里涉及到一個概念,就是事務(wù)。一個事務(wù)是指一個客戶機向服務(wù)器發(fā)送請求然后服務(wù)器做出反應的過程??蛻魴C在發(fā)送請求時開始計時,收到服務(wù)器響應后結(jié)束計時,以此來計算使用的時間和完成的事務(wù)個數(shù)。
- QPS:英文全稱是 Queries Per Second,即每秒查詢率。QPS 是對一個特定的查詢服務(wù)器在規(guī)定時間內(nèi)所處理流量多少的衡量標準。舉個例子:假設(shè)數(shù)據(jù)庫處理一條 SQL 需要 10ms,那么 1s 就可以處理 100 條 SQL,那么我們說它 QPS<=100;假設(shè)數(shù)據(jù)庫處理一條 SQL 需要 100ms,那么 1s 就可以處理 10 條 SQL,那么我們說它 QPS<=10。
我們常用 QPS 和 TPS 來衡量 SQL 的處理效率。
數(shù)據(jù)庫連接被占滿
這個好理解,數(shù)據(jù)庫的連接數(shù)必然是有限的,在 MySQL 中,我們可以通過 max_connections 來設(shè)置數(shù)據(jù)庫的連接數(shù)(這個值默認是 100,生產(chǎn)環(huán)境下這個值可以適當調(diào)大)。慢 SQL 由于處理時間較長,因此占用數(shù)據(jù)庫連接的時間也較長,在高并發(fā)環(huán)境下這樣就容易導致數(shù)據(jù)庫連接被占滿。
超高的 CPU 使用率
慢 SQL 還會導致超高的 CPU 使用率,超高的 CPU 使用率會導致 CPU 資源耗盡進而出現(xiàn)宕機。
慢 SQL 真的危害很大!
2.數(shù)據(jù)庫服務(wù)器配置
這個應該好理解,不需要我多說吧。
服務(wù)器的硬件如 CPU、內(nèi)存、磁盤 IO 等都會影響到 MySQL 性能,操作系統(tǒng)也會影響到 MySQL 性能。
3.網(wǎng)卡流量
網(wǎng)卡流量當然也會影響數(shù)據(jù)庫。網(wǎng)卡 IO 被占滿了一樣也是沒法操作數(shù)據(jù)庫,那么如何避免這一情況呢?
- 減少從服務(wù)器的數(shù)量,因為從服務(wù)器需要從主服務(wù)器同步數(shù)據(jù),會占用網(wǎng)卡 IO(當然是在合理的范圍內(nèi)減少從服務(wù)器的數(shù)量)。
- 數(shù)據(jù)分級緩存,避免突然的緩存失效對數(shù)據(jù)庫形成沖擊。
- 避免 select *,不僅浪費時間,還浪費網(wǎng)絡(luò)流量。
- 分離業(yè)務(wù)網(wǎng)絡(luò)和服務(wù)器網(wǎng)絡(luò)。
4.磁盤 IO
磁盤 IO 對數(shù)據(jù)庫性能的影響也是顯而易見的,因為數(shù)據(jù)庫無論怎么管理數(shù)據(jù),最終都是要存入到硬盤中的,所以磁盤 IO 對數(shù)據(jù)庫的影響也就非常重要了。但是這個問題的解決,就只能使用更好更快的磁盤設(shè)備,例如 SSD。
另外,我們?nèi)粘?赡芏紩幸恍┒〞r的磁盤維護計劃,在一些高并發(fā)場景下(如促銷、618,雙11等),我們就需要調(diào)整磁盤維護計劃,避免在這些時候進行磁盤維護。同時一些大量消耗磁盤 IO 的工作如備份也需要在這個時候調(diào)整一下,例如原本在主庫上做的數(shù)據(jù)備份工作,在大促期間可以放到從庫上面做。
5.大表操作
大表操作也會影響到數(shù)據(jù)庫性能,那么什么樣的表就算大表呢?
大表沒有統(tǒng)一的標準,還是要結(jié)合具體的業(yè)務(wù)場景來定。
我舉一個比較常規(guī)的例子:
- 數(shù)據(jù)表中的行數(shù)超過千萬行。
- 數(shù)據(jù)表文件超過 10G。
當然,上面這個定義并不是絕對的,如果是一個操作日志表,日志表一般只會涉及到插入和簡單的查詢,基本上不會有 delete 和 update,那么對于這種表,即使超過了千萬行,也并不會影響我們的業(yè)務(wù)。但是如果是訂單表等業(yè)務(wù)表,超過千萬行就要小心了。
大表究竟會帶來哪些問題呢?
- 慢查詢:畢竟數(shù)據(jù)量大了,想要過濾出自己想要的數(shù)據(jù),肯定費時間。從上千萬上億條數(shù)據(jù)中找出自己想要的數(shù)據(jù),也會產(chǎn)生大量的磁盤 IO。
- DDL 操作恐怖:在大表上進行表定義操作也是一件非??植赖氖虑?,例如建立索引、添加/刪除 字段,想想都可怕。在 MySQL5.5(不含) 之前,建立索引是會鎖表的,從 MySQL5.5(含) 開始,建立索引雖然不會鎖表,但是會引起主從延遲(因為要在主庫上操作完成之后,再將操作日志傳到從庫,然后完成同步)。
這就是大表所帶來的問題,一般來說,我們有兩種常見的解決思路:
- 分庫分表
- 歷史數(shù)據(jù)歸檔
至于什么時候用分庫分表,什么時候用歷史數(shù)據(jù)歸檔,這個松哥在以后的文章中再和大家介紹。
6.大事務(wù)操作
一些運行時間比較長,涉及到數(shù)據(jù)比較多的事務(wù),我們可以稱之為大事務(wù)。大事務(wù)會鎖定很多條數(shù)據(jù)進行處理,這樣就容易造成大量的阻塞和鎖超時,并且一旦出錯發(fā)生回滾,回滾所需要的時間也會比較長,而且在回滾期間數(shù)據(jù)依然處于被鎖的狀態(tài)。
同時,由于大事務(wù)耗時較長,需要等到主庫事務(wù)執(zhí)行完畢后,將操作日志寫入 binlog,然后從庫讀取 binlog 進行同步,這樣勢必會導致主從延遲。
解決大事務(wù),兩個思路:
- 避免一次性處理太多數(shù)據(jù)。
- 移除事務(wù)中不必要的 SELECT 操作。
具體的操作方式,我們將在以后的文章中介紹。
7.存儲引擎
使用 MySQL 我們可以選擇不同的存儲引擎,不同的存儲引擎特點不同,最終對數(shù)據(jù)庫的影響也不同。例如 MySQL 中常見的 MyISAM、InnoDB 等存儲引擎。
MyISAM 不支持事務(wù),而且是表級鎖;InnoDB 是事務(wù)級存儲引擎,支持行級鎖,也支持事務(wù)的 ACID 特性。
那么是不是說 InnoDB 就一定比 MyISAM 好呢?也不一定!這個還是要看具體的使用場景。
8.數(shù)據(jù)庫參數(shù)配置
大家都知道數(shù)據(jù)庫有很多配置參數(shù),我們在數(shù)據(jù)庫優(yōu)化時可對其進行配置,例如前面所說的 max_connections。這些參數(shù)中,有的參數(shù)對數(shù)據(jù)庫的性能影響較大,有的則影響較小,這個我們在以后的文章中再和大家詳細討論。
好啦,今天主要和小伙伴們探討了在我們?nèi)粘i_發(fā)中,到底有哪些東西會影響數(shù)據(jù)庫的性能!至于具體的解決方案,松哥將在接下來的文章中和大家細聊。
雖然我們不是專業(yè)的 DBA,但是從小伙伴們的面試經(jīng)歷來看,數(shù)據(jù)庫優(yōu)化顯然也不能一竅不通。
本文轉(zhuǎn)載自微信公眾號「江南一點雨」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系江南一點雨公眾號。