基於MySQL 的 SQL 優化總結

来源:https://www.cnblogs.com/itzhouq/archive/2020/05/17/mysql1.html
-Advertisement-
Play Games

在資料庫運維過程中,優化 SQL 是 DBA 團隊的日常任務。例行 SQL 優化,不僅可以提高程式性能,還能減低線上故障的概率。 目前常用的 SQL 優化方式包括但不限於:業務層優化、SQL 邏輯優化、索引優化等。其中索引優化通常通過調整索引或新增索引從而達到 SQL 優化的目的。索引優化往往可以... ...


文章首發於我的個人博客,歡迎訪問。https://blog.itzhouq.cn/mysql1

基於MySQL 的 SQL 優化總結

在資料庫運維過程中,優化 SQL 是 DBA 團隊的日常任務。例行 SQL 優化,不僅可以提高程式性能,還能減低線上故障的概率。

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

--- 來自美團技術團隊

SQL 優化是一個複雜的問題,不同版本和種類的資料庫、不同數據級的數據需要選擇不同的優化策略。

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

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

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

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

原則二:通過索引優化。

這兩個涉及的點比較多,他們之間也是有聯繫的,下麵詳細說說。

1、避免全表掃描

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

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

對 where 和 order by 涉及的列建立索引可以提高訪問速度。但是要註意,並不是你建立了索引,索引就一定會生效。如果沒有生效查詢時還是全表掃描,速度還是得不到提升。那如何判斷索引沒有生效呢?可以藉助 explain + SQL 語句的結果判斷。大佬寫的MySQL EXPLAIN 命令: 查看查詢執行計劃中總結了用法。簡單的說,使用該命令分析的結果中很多欄位,其中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、索引優化

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

1、使用聯合索引時,註意索引列的順序,一般遵循最左匹配原則

比如一個索引:

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

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

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

當我們創建的這個聯合索引,就相當於創建了(userid)(userid, age)兩個索引。聯合索引不滿足最左原則,一般會失效,但是這個還跟 MySQL 優化器有關係。

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

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

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

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

3、刪除冗餘索引

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

比如,索引(A, B)相當於創建了索引(A)和索引(A, B)

4、註意索引的數量

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

5、索引不適合建立在有大量重覆的欄位上,如性別這類欄位

3、其他

其他原則包括但不限於:

1、查詢 SQL 儘量不要使用 select *,而是 select 某欄位

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

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

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

阿裡巴巴開發手冊中規定超過三個表禁止 join的,但是這些規範的適用性還是要考慮環境。當連表數量較少時,連表路徑演算法選擇的是動態規划算法;但是連表太多的情況下,路徑演算法可能退化成貪心演算法,連表的方案可能不是最優的的。

這種情況下,如何寫 SQL 呢?答案是通過可以通過冗餘實現,細節就不展開了。

4、通過工具分析 SQL

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

4.1 MySQL 自帶的慢查詢日誌

MySQL 的慢查詢日誌是 MySQL 提供的一種日誌,記錄,用於記錄在 MySQL 中響應時間超過設定的閾值的語句。在 MySQL 的配置文件 my.ini中開啟後,支持將慢查詢日誌寫入文件或者資料庫。通過explain關鍵詞模擬優化器執行 SQL,分析慢查詢 SQL。

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

4.2 日誌分析工具 MySQLdumpslow

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

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

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

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

參考文章:

MySQL 快速入門

MySQL 事務機制

MySQL EXPLAIN 命令: 查看查詢執行計劃

MySQL 索引與查詢優化

書寫高質量的 SQL 總結

索引優化的原則總結

美團點評SQL優化工具SQLAdvisor開源


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如何在Vmware安裝Linux CentOS 7.7系統,並且是最小化安裝。之後進行必要的配置修改,並實現基礎優化。最後做一個快照。 ...
  • cat選項分析 選項解析: -A, --show-all 等價於 -vET -b, --number-nonblank 對非空輸出行(包括僅僅有空格的行)編號,空輸出行,指的是該行沒有任何內容,即連續2次敲擊回車按鈕。 -e 等價於 -vE -E, --show-ends 在每行結束處顯示 $ -n ...
  • 一個Linux系統,根據版本不同,大約包含240~260個系統調用。為了使得操作更為簡單,更加便於應用程式使用,Linux系統對系統調用的部分功能進行了再次封裝,形成了公用函數庫,以供應用程式調用。公用函數庫中的一個方法,實質上是若幹個系統調用以特定的邏輯組合而成。 ...
  • 如果現在需要在 Linux 伺服器上執行一系列命令(比如搭建 LNMP 環境)我應該會第一時間想到想辦法寫個 Shell 腳本,然後扔上去執行以下看看結果。 然而一貫懶惰的我並不想這麼去執行 Shell 和一些重覆命令。所以俺尋思可以有個方法本地直接在伺服器端執行腳本,尋思生異端,這時候有某大技霸告 ...
  • 0 個人信息 張櫻姿 201821121038 計算1812 1 實驗目的 通過編程進一步瞭解記憶體管理。 2 實驗內容 在伺服器上用Vim編寫一個程式:模擬實現某個記憶體管理演算法,測試給出結果,並對解釋運行結果。 3 實驗報告 3.1 記錄記憶體空間使用情況 使用鏈表記錄記憶體空間使用情況。 1 //每個 ...
  • 來源: CentOS 8.0 創建管理LVM分區(掛載新分區) https://www.iwmyx.cn/centos80cjgllvmfa.html 1.查看可用磁碟 fdisk -l 2.新盤(/dev/sdb)創建分區 fdisk /dev/sdb 創建/dev/sdb1 分區,並設置分區類型 ...
  • 在Ubuntu18.04中,傳統的配置/etc/network/interfaces已無用,新的網路配置文件在:/etc/netplan/50-cloud-init.yaml 用vim進行編輯文件 註意格式 冒號後邊有個空格 network: ethernets: ens33: dhcp4: fal ...
  • 前一篇博文中主要說了下,lxc容器在Linux上的簡單管理,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/12901493.html;今天我們來介紹下lxc的圖像管理工具LXC WEB Panel;   項目下載地址:https://github.com/... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...