松哥原創的 Spring Boot 視訊教程已經殺青,感興趣的小夥伴戳這裡-->Spring Boot+Vue+微人事視訊教程
松哥有兩個小夥伴最近在幫人改造一個系統,對方原本的系統是一個用 Java GUI 做的桌面應用,現在要用 Spring Boot 改造成一個 Web 應用。原本的應用在 Mac 上運作的時候非常絲滑,但是在 Windows 上運作的時候,就特别卡。經過分析之後,發現是因為資料庫中資料量過大導緻每一次的查詢都非常緩慢。
為了解決這一問題,他們特地來咨詢了松哥,我也趁此機會整理了一下資料庫優化的基本操作,形成了幾篇文章,接下來就和小夥伴們逐一分享。
今天我們主要來看下,到底是什麼影響了資料庫的性能?找到問題的原因,才能解決問題。
整體上來說,影響資料庫性能的因素,我們可以歸為以下幾個方面:
- SQL 腳本
- 資料庫伺服器配置
- 網卡流量
- 磁盤 IO
- 大表操作
- 大事務操作
- 存儲引擎
- 資料庫參數配置
接下來我們就從這幾個方面來逐一進行說明。
1. SQL 腳本
SQL 腳本會影響到 MySQL 的執行效率,這個大家都懂,面試八股文中常見問題之一。其實也不是面試官故意愛考這個問題,隻是這個東西太重要了,根據松哥的經驗,80% 的資料庫問題,都是由慢 SQL 導緻的,都可以通過 SQL 優化來解決,是以 SQL 優化技能對于開發者而言就非常重要了(有條件的公司也可以聘請 DBA,但是大部分公司是沒有 DBA 的),這也是為什麼我們在面試時經常會遇到 SQL 優化的原因。
那麼慢 SQL 究竟會帶來哪些風險呢?
超高的 QPS 和 TPS
可能有人還不清楚什麼是 QPS 和 TPS,是以我們這裡先對這兩個做一個簡單介紹。
- TPS:英文全稱是 Transactions Per Second,即伺服器每秒處理的事務數。TPS 包括一條消息入和一條消息出,加上一次使用者資料庫通路。這裡涉及到一個概念,就是事務。一個事務是指一個客戶機向伺服器發送請求然後伺服器做出反應的過程。客戶機在發送請求時開始計時,收到伺服器響應後結束計時,以此來計算使用的時間和完成的事務個數。
- QPS:英文全稱是 Queries Per Second,即每秒查詢率。QPS 是對一個特定的查詢伺服器在規定時間内所處理流量多少的衡量标準。舉個例子:假設資料庫處理一條 SQL 需要 10ms,那麼 1s 就可以處理 100 條 SQL,那麼我們說它
;假設資料庫處理一條 SQL 需要 100ms,那麼 1s 就可以處理 10 條 SQL,那麼我們說它QPS<=100
。QPS<=10
我們常用 QPS 和 TPS 來衡量 SQL 的處理效率。
資料庫連接配接被占滿
這個好了解,資料庫的連接配接數必然是有限的,在 MySQL 中,我們可以通過 max_connections 來設定資料庫的連接配接數(這個值預設是 100,生産環境下這個值可以适當調大)。慢 SQL 由于處理時間較長,是以占用資料庫連接配接的時間也較長,在高并發環境下這樣就容易導緻資料庫連接配接被占滿。
超高的 CPU 使用率
慢 SQL 還會導緻超高的 CPU 使用率,超高的 CPU 使用率會導緻 CPU 資源耗盡進而出現當機。
慢 SQL 真的危害很大!
2.資料庫伺服器配置
這個應該好了解,不需要我多說吧。
伺服器的硬體如 CPU、記憶體、磁盤 IO 等都會影響到 MySQL 性能,作業系統也會影響到 MySQL 性能。
3.網卡流量
網卡流量當然也會影響資料庫。網卡 IO 被占滿了一樣也是沒法操作資料庫,那麼如何避免這一情況呢?
- 減少從伺服器的數量,因為從伺服器需要從主伺服器同步資料,會占用網卡 IO(當然是在合理的範圍内減少從伺服器的數量)。
- 資料分級緩存,避免突然的緩存失效對資料庫形成沖擊。
- 避免
,不僅浪費時間,還浪費網絡流量。select *
- 分離業務網絡和伺服器網絡。
4.磁盤 IO
磁盤 IO 對資料庫性能的影響也是顯而易見的,因為資料庫無論怎麼管理資料,最終都是要存入到硬碟中的,是以磁盤 IO 對資料庫的影響也就非常重要了。但是這個問題的解決,就隻能使用更好更快的磁盤裝置,例如 SSD。
另外,我們日常可能都會有一些定時的磁盤維護計劃,在一些高并發場景下(如促銷、618,雙11等),我們就需要調整磁盤維護計劃,避免在這些時候進行磁盤維護。同時一些大量消耗磁盤 IO 的工作如備份也需要在這個時候調整一下,例如原本在主庫上做的資料備份工作,在大促期間可以放到從庫上面做。
5.大表操作
大表操作也會影響到資料庫性能,那麼什麼樣的表就算大表呢?
大表沒有統一的标準,還是要結合具體的業務場景來定。
我舉一個比較正常的例子:
- 資料表中的行數超過千萬行。
- 資料表檔案超過 10G。
當然,上面這個定義并不是絕對的,如果是一個記錄檔表,日志表一般隻會涉及到插入和簡單的查詢,基本上不會有 delete 和 update,那麼對于這種表,即使超過了千萬行,也并不會影響我們的業務。但是如果是訂單表等業務表,超過千萬行就要小心了。
大表究竟會帶來哪些問題呢?
- 慢查詢:畢竟資料量大了,想要過濾出自己想要的資料,肯定費時間。從上千萬上億條資料中找出自己想要的資料,也會産生大量的磁盤 IO。
- DDL 操作恐怖:在大表上進行表定義操作也是一件非常恐怖的事情,例如建立索引、添加/删除 字段,想想都可怕。在 MySQL5.5(不含) 之前,建立索引是會鎖表的,從 MySQL5.5(含) 開始,建立索引雖然不會鎖表,但是會引起主從延遲(因為要在主庫上操作完成之後,再将記錄檔傳到從庫,然後完成同步)。
這就是大表所帶來的問題,一般來說,我們有兩種常見的解決思路:
- 分庫分表
- 曆史資料歸檔
至于什麼時候用分庫分表,什麼時候用曆史資料歸檔,這個松哥在以後的文章中再和大家介紹。
6.大事務操作
一些運作時間比較長,涉及到資料比較多的事務,我們可以稱之為大事務。大事務會鎖定很多條資料進行處理,這樣就容易造成大量的阻塞和鎖逾時,并且一旦出錯發生復原,復原所需要的時間也會比較長,而且在復原期間資料依然處于被鎖的狀态。
同時,由于大事務耗時較長,需要等到主庫事務執行完畢後,将記錄檔寫入 binlog,然後從庫讀取 binlog 進行同步,這樣勢必會導緻主從延遲。
解決大事務,兩個思路:
- 避免一次性處理太多資料。
- 移除事務中不必要的 SELECT 操作。
具體的操作方式,我們将在以後的文章中介紹。
7.存儲引擎
使用 MySQL 我們可以選擇不同的存儲引擎,不同的存儲引擎特點不同,最終對資料庫的影響也不同。例如 MySQL 中常見的 MyISAM、InnoDB 等存儲引擎。
MyISAM 不支援事務,而且是表級鎖;InnoDB 是事務級存儲引擎,支援行級鎖,也支援事務的 ACID 特性。
那麼是不是說 InnoDB 就一定比 MyISAM 好呢?也不一定!這個還是要看具體的使用場景。
8.資料庫參數配置
大家都知道資料庫有很多配置參數,我們在資料庫優化時可對其進行配置,例如前面所說的 max_connections。這些參數中,有的參數對資料庫的性能影響較大,有的則影響較小,這個我們在以後的文章中再和大家詳細讨論。
好啦,今天主要和小夥伴們探讨了在我們日常開發中,到底有哪些東西會影響資料庫的性能!至于具體的解決方案,松哥将在接下來的文章中和大家細聊。
雖然我們不是專業的 DBA,但是從小夥伴們的面試經曆來看,資料庫優化顯然也不能一竅不通。