电竞比分网-中国电竞赛事及体育赛事平台

分享

基于MySQL 的 SQL 優(yōu)化總結

 新進小設計 2022-03-24

在數據庫運維過程中,優(yōu)化 SQL 是 DBA 團隊的日常任務。例行 SQL 優(yōu)化,不僅可以提高程序性能,還能減低線上故障的概率。

目前常用的 SQL 優(yōu)化方式包括但不限于:業(yè)務層優(yōu)化、SQL 邏輯優(yōu)化、索引優(yōu)化等。其中索引優(yōu)化通常通過調整索引或新增索引從而達到 SQL 優(yōu)化的目的。索引優(yōu)化往往可以在短時間內產生非常巨大的效果。

--- 來自美團技術團隊

SQL 優(yōu)化是一個復雜的問題,不同版本和種類的數據庫、不同數據級的數據需要選擇不同的優(yōu)化策略。

說明:我這里簡單總結一下 SQL 優(yōu)化,很多的大佬寫過這方面的細節(jié)和用法,甚至還有相關的案例。我只是作為一個階段性的總結,肯定是不全面的。如有錯誤和不當之處,歡迎批評指正,不勝感激。

從日常開發(fā)寫 SQL 的角度看,需要遵循一些規(guī)則,但是這些規(guī)則只能解決部分問題。因為隨著開發(fā)和數據量的增長,SQL 還是會變慢,這個時候需要一些針對性的措施,比如針對性地添加索引,通過命令或者工具分析變慢的 SQL 等等。

說說 SQL 優(yōu)化的其中兩個大的原則(肯定還有別的):

原則一:盡量避免全表掃描。

原則二:通過索引優(yōu)化。

這兩個涉及的點比較多,他們之間也是有聯(lián)系的,下面詳細說說。

1、避免全表掃描

為啥要避免全表掃描呢?因為全表掃描耗費更多的時間。

那么從哪些方法避免全表掃描呢?

對 where 和 order by 涉及的列建立索引可以提高訪問速度。但是要注意,并不是你建立了索引,索引就一定會生效。如果沒有生效查詢時還是全表掃描,速度還是得不到提升。那如何判斷索引沒有生效呢?可以借助 explain + SQL 語句的結果判斷。大佬寫的MySQL EXPLAIN 命令: 查看查詢執(zhí)行計劃中總結了用法。簡單的說,使用該命令分析的結果中很多字段,其中type 描述了查詢的方式,如果 type 的結果是ALL,那么索引肯定沒起作用。下面總結一下如何避免索引失效。

1、避免在 where 子句中對字段進行 null 判斷

select id from user where name is null

2、避免在 where 子句使用 != 或者 <>

3、避免在 where 子句中對表達式進行操作

select id from user where age/2 = 20

修改為:

select id from user where age = 20 * 2

4、避免在 where 子句中對字段進行函數操作

5、避免在 like 查詢中將 %放在開頭

select id from user where username like '%wh'

2、索引優(yōu)化

適當地添加索引可以提高 SQL 的速度,但也有些注意點。

1、使用聯(lián)合索引時,注意索引列的順序,一般遵循最左匹配原則

比如一個索引:

KEY `idx_userid_age` (`userId`, `age`) USING BTREE

符合最左匹配原則的寫法是把userid放在前面

select userid, name from user where userid = 1001 and age = 10

當我們創(chuàng)建的這個聯(lián)合索引,就相當于創(chuàng)建了(userid)(userid, age)兩個索引。聯(lián)合索引不滿足最左原則,一般會失效,但是這個還跟 MySQL 優(yōu)化器有關系。

2、在適當的時候,使用覆蓋索引

通常在使用索引檢索數據之后,需要訪問磁盤上數據表文件讀取所需要的列,這種操作成為“回表”。

若索引中包含查詢的所有列,則不需要回表操作,直接從索引文件中讀取數據即可,這種索引成為“覆蓋索引”。

在查詢時盡量減少select *,只查詢需要的行,條件允許時盡量建立覆蓋索引。

3、刪除冗余索引

索引并不是越多越好,冗余的索引會影響性能。

比如,索引(A, B)相當于創(chuàng)建了索引(A)和索引(A, B)。

4、注意索引的數量

索引不是越多越好,一般不要超過 5 個。索引雖然提高了查詢效率,但是也會降低插入和更新的效率。插入或更新可能會重建索引,索引建立索引也需要慎重考慮。

5、索引不適合建立在有大量重復的字段上,如性別這類字段

3、其他

其他原則包括但不限于:

1、查詢 SQL 盡量不要使用 select *,而是 select 某字段。

2、連表查詢的時候盡量將數據量少的表驅動數據多的表。

3、如果插入的數據較多時,考慮批量插入。

4、原則上不要有超過 5 張以上的表連接

阿里巴巴開發(fā)手冊中規(guī)定超過三個表禁止 join的,但是這些規(guī)范的適用性還是要考慮環(huán)境。當連表數量較少時,連表路徑算法選擇的是動態(tài)規(guī)劃算法;但是連表太多的情況下,路徑算法可能退化成貪心算法,連表的方案可能不是最優(yōu)的的。

這種情況下,如何寫 SQL 呢?答案是通過可以通過冗余實現(xiàn),細節(jié)就不展開了。

4、通過工具分析 SQL

說說幾個用到的 SQL 分析工具

4.1 MySQL 自帶的慢查詢日志

MySQL 的慢查詢日志是 MySQL 提供的一種日志,記錄,用于記錄在 MySQL 中響應時間超過設定的閾值的語句。在 MySQL 的配置文件 my.ini中開啟后,支持將慢查詢日志寫入文件或者數據庫。通過explain關鍵詞模擬優(yōu)化器執(zhí)行 SQL,分析慢查詢 SQL。

分析相關語句使用了哪些表、連接的類型、掃描的行數、使用的索引等。

4.2 日志分析工具 MySQLdumpslow

在生產環(huán)境中,手工分析日志、查找 SQL 比較費時間。MySQL 提供的 MySQLdumpslow 工具可以得到一些 SQL 訪問的統(tǒng)計數據,比如訪問次數最多的 10 條 SQL 等。

4.3 第三方工具:美團技術團隊的 SQLAdvisor

由美團技術團隊維護的一個開源的分析 SQL,給出索引優(yōu)化建議的工具。

只是大概做了個總結,細節(jié)都沒有展開,有興趣的同學自行學習吧。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多