mysql優化指南之原理篇

之前碰到一個線上問題,在接手一個同事的項目后,因為工期比較趕,我還沒來得及了解業務背景和大致實現,只是了解了上線發布的順序和驗證方式就進行了上線,在上線進行金絲雀的時候系統還沒發生什么異常,于是我們進行了全量發布,全量完成后監控顯示有一個接口在間歇性的顯示耗時會比較長,然后我們在觀察是否影響面和判斷是否需要回滾中。另一方面在我們全量發布后大約10分鐘后,其他一個業務線就進行了緊急告警,但是他們沒有上線,在眾多排查手段用了之后,dba排查到我們系統的庫和他們的業務系統庫用的是一個機器,所以告知我們,然后我們就執行了回滾步驟中的關閉業務開關,關閉后雙方業務的監控表明問題消失了。

之后我們就進行解析問題,發現是在某些業務邏輯中操作的一個查詢沒有走索引導致的,然后在下一個窗口進行了重新上線,接口耗時和對方業務的告警都沒有了。但是在上線一段時間后,在夜里2點到5點的時候,該系統仍然會顯示一些實時接口間歇耗時,然后我們看了那段時間的系統運行情況,發現其中一個定時任務會那段時間運行,應該是兩者爭相使用數據庫連接池導致的,最終在測試環境復現,在擴大數據庫連接池后問題消失。

這次情況給我的啟示就是一定要注重了解學會了解清楚怎樣承接一個工程,和在數據庫優化這塊的知識,所以我就進行了一些mysql優化所學的整理,分享給大家。要了解清楚索引的使用情況、連接池情況和數據庫的部署是混合部署還是獨立部署。

關于數據庫的優化,本次是想先講明數據的一些原理,然后再進行一些優化的講解。

一、mysql的原理

(一)mysql體系結構

首先我們來了解下mysql系統是怎樣的,如下圖:

MySQL Server架構自頂向下大致可以分網絡連接層、服務層、存儲引擎層和系統文件層。

1.網絡連接層

客戶端連接器(Client Connectors):提供與MySQL服務器建立的支持。目前幾乎支持所有主流

的服務端編程技術,例如常見的 Java、C、Python、.NET等,它們通過各自API技術與MySQL建立連接。

2.服務層(MySQL Server)

服務層是MySQL Server的核心,主要包含系統管理和控制工具、連接池、SQL接口、解析器、查詢優

化器和緩存六個部分:

(1)連接池(Connection Pool):負責存儲和管理客戶端與數據庫的連接,一個線程負責管理一個

連接。

(2)系統管理和控制工具(Management Services & Utilities):例如備份恢復、安全管理、集群

管理等

(3)SQL接口(SQL Interface):用于接受客戶端發送的各種SQL命令,并且返回用戶需要查詢的結

果。比如DML、DDL、存儲過程、視圖、觸發器等。

(4)解析器(Parser):負責將請求的SQL解析生成一個"解析樹"。然后根據一些MySQL規則進一步

檢查解析樹是否合法。

(5)查詢優化器(Optimizer):當“解析樹”通過解析器語法檢查后,將交由優化器將其轉化成執行計

劃,然后與存儲引擎交互。

select uid,name from user where gender=1;

選取--》投影--》聯接 策略

1)select先根據where語句進行選取,并不是查詢出全部數據再過濾

2)select查詢根據uid和name進行屬性投影,并不是取出所有字段

3)將前面選取和投影聯接起來最終生成查詢結果

(6)緩存(Cache&Buffffer):

緩存機制是由一系列小緩存組成的。比如表緩存,記錄緩存,權限緩

存,引擎緩存等。如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據。

3.存儲引擎層(Pluggable Storage Engines)

存儲引擎負責MySQL中數據的存儲與提取,與底層系統文件進行交互。MySQL存儲引擎是插件式的,

服務器中的查詢執行引擎通過接口與存儲引擎進行通信,接口屏蔽了不同存儲引擎之間的差異 。現在有

很多種存儲引擎,各有各的特點,最常見的是MyISAM和InnoDB。

4.系統文件層(File System)

該層負責將數據庫的數據和日志存儲在文件系統之上,并完成與存儲引擎的交互,是文件的物理存儲

層。主要包含日志文件,數據文件,配置文件,pid 文件,socket 文件等。

(1)配置文件:用于存放MySQL所有的配置信息文件,比如my.cnf、my.ini等。

(2)數據文件:

db.opt 文件:記錄這個庫的默認使用的字符集和校驗規則。

frm 文件:存儲與表相關的元數據(meta)信息,包括表結構的定義信息等,每一張表都會

有一個frm 文件。

MYD 文件:MyISAM 存儲引擎專用,存放 MyISAM 表的數據(data),每一張表都會有一個

.MYD 文件。

MYI 文件:MyISAM 存儲引擎專用,存放 MyISAM 表的索引相關信息,每一張 MyISAM 表對

應一個 .MYI 文件。

ibd文件和 IBDATA 文件:存放 InnoDB 的數據文件(包括索引)。InnoDB 存儲引擎有兩種

表空間方式:獨享表空間和共享表空間。獨享表空間使用 .ibd 文件來存放數據,且每一張

InnoDB 表對應一個 .ibd 文件。共享表空間使用 .ibdata 文件,所有表共同使用一個(或多

個,自行配置).ibdata 文件。

ibdata1 文件:系統表空間數據文件,存儲表元數據、Undo日志等 。

ib_logfifile0、ib_logfifile1 文件:Redo log 日志文件。

(二)?sql執行流程

sql執行的流程一般是這樣的,如下圖:

1.建立連接(Connectors&Connection Pool),通過客戶端/服務器通信協議與MySQL建立連接。MySQL 客戶端與服務端的通信方式是 “ 半雙工 ”。

2.查詢緩存(Cache&Buffffer)

這是MySQL的一個可優化查詢的地方,如果開啟了查詢緩存且在

查詢緩存過程中查詢到完全相同的SQL語句,則將查詢結果直接返回給客戶端;如果沒有開啟查詢

緩存或者沒有查詢到完全相同的 SQL 語句則會由解析器進行語法語義解析,并生成“解析樹”。

緩存Select查詢的結果和SQL語句

執行Select查詢時,先查詢緩存,判斷是否存在可用的記錄集,要求是否完全相同(包括參

數值),這樣才會匹配緩存數據命中。

即使開啟查詢緩存,以下SQL也不能緩存

查詢語句使用SQL_NO_CACHE

查詢的結果大于query_cache_limit設置

查詢中有一些不確定的參數,比如now()

show variables like '%query_cache%'; //查看查詢緩存是否啟用,空間大小,限制等

show status like 'Qcache%'; //查看更詳細的緩存參數,可用緩存空間,緩存塊,緩存多少等

3.解析器(Parser)將客戶端發送的SQL進行語法解析,生成"解析樹"。預處理器根據一些MySQL

規則進一步檢查“解析樹”是否合法,例如這里將檢查數據表和數據列是否存在,還會解析名字和別

名,看看它們是否有歧義,最后生成新的“解析樹”。

4.查詢優化器(Optimizer)根據“解析樹”生成最優的執行計劃。MySQL使用很多優化策略生成最

優的執行計劃,可以分為兩類:靜態優化(編譯時優化)、動態優化(運行時優化)。

5.查詢執行引擎負責執行 SQL 語句,此時查詢執行引擎會根據 SQL 語句中表的存儲引擎類型,以

及對應的API接口與底層存儲引擎緩存或者物理文件的交互,得到查詢結果并返回給客戶端。若開

啟用查詢緩存,這時會將SQL 語句和結果完整地保存到查詢緩存(Cache&Buffffer)中,以后若有

相同的 SQL 語句執行則直接返回結果。

如果開啟了查詢緩存,先將查詢結果做緩存操作,返回結果過多,采用增量模式返回

(三)sql語句的中關鍵字執行順序

在編寫一條查詢語句時,習慣性的從頭到尾開始敲出來,應該都是從select?開始吧,但似乎沒太注意它們真正的執行順序;既然要優化,肯定需要得知道一條SQL語句大概的執行流程,結合執行計劃,目的就更加清晰啦;上一張一看就明白的圖:

關鍵字簡述:

  • FROM:確定數據來源,即指定表;
  • JOIN...ON:確定關聯表和關聯條件;
  • WHERE:指定過濾條件,過濾出滿足條件的數據;
  • GROUP BY:按指定的字段對過濾后的數據進行分組;
  • HAVING:對分組之后的數據指定過濾條件;
  • SELECT:查找想要的字段數據;
  • DISTINCT:針對查找出來的數據進行去重;
  • ORDER BY:對去重后的數據指定字段進行排序;
  • LIMIT:對去重后的數據限制獲取到的條數,即分頁;

(四)?mysql使用到的硬件

mysql使用硬件主要的工作內容如下:

CPU及內存:緩存數據訪問、比較、排序、事務檢測、SQL解析、函數或邏輯運算;

網絡:結果數據傳輸、SQL請求、遠程數據庫訪問(dblink);

硬盤:數據訪問、數據寫入、日志記錄、大數據量排序、大表連接。

下面我們看下硬件資源的CPU、內存、硬盤、網卡的性能指標。

從圖上可以看到基本上每種設備都有兩個指標:

延時(響應時間):表示硬件的突發處理能力;

帶寬(吞吐量):代表硬件持續處理能力。

從上圖可以看出,計算機系統硬件性能從高到代依次為:

CPU——Cache(L1-L2-L3)——內存——SSD硬盤——網絡——硬盤

(五)存儲引擎

存儲數據時,影響存儲速度的主要是索引、唯一性校驗、一次存儲的數據條數等。存儲數據的優化,不同的存儲引擎優化手段不一樣,在MySQL中常用的存儲引擎有,MyISAM和InnoDB,下面來簡單介紹下:

MyISAM

InnoDB

物理文件構成區別

MyISAM表是獨立于操作系統的,每當我們建立一個MyISAM引擎的表時,就會在本地磁盤上建立三個文件,分別是

“.frm”表元數據定義

“.MYD”數據存儲

“.MYI”存儲索引

Innodb的所有數據保存在一個單獨的表空間里面,而這個表空間可以由很多個文件組成,一個表可以跨多個文件存在。基于磁盤的資源是InnoDB表空間數據文件和它的日志文件,InnoDB 表的大小只受限于操作系統文件的大小,一般為?2GB

事務處理

MyISAM并不支持事務這樣的高級數據庫特性,但MyISAM類型的表強調的是執行性能。

InnoDB提供對事務的支持、外鍵約束。

MyISAM存儲引擎只支持表鎖,鎖的粒度較粗。

提供行鎖,不過需要注意的是,如果在執行一個SQL語句時MySQL不能確定要掃描的范圍,InnoDB表同樣會鎖全表,例如update table set num=1 ?where name like “%aaa%”

索引的結構

MyISAM引擎使用B+Tree作為索引結構。MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,讀取相應數據記錄。

InnoDB引擎用的也是B+Tree作為索引結構。在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。

DB的CRUD操作

MyISAM比較適合執行大量查詢的操作,在篩選大量數據時候非常迅速是其的特點。

執行大量的insert或update,出于性能方面的考慮,應該使用InnoDB表。

場景

?MyISAM管理非事務表,它提供高速存儲和檢索,以及全文搜索能力,適合需要執行大量的SELECT查詢類似數據倉庫這樣查詢頻繁的應用。

InnoDB用于事務處理應用程序,具有眾多特性,包括ACID事務支持。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多用戶并發操作的性能。

如上面表格中“索引的結構”一欄所述,MyISAM存儲引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址。下面是MyISAM中索引的原理圖:

MyISAM中索引檢索的算法先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,讀取相應數據記錄。這里我們假設這個表僅有三列,分別是Col1、Col2和Col3列。在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。假設我們在Col2列上建立一個輔助索引則索引結構如下:

雖然InnoDB也是使用B+Tree作為索引結構,但是具體實現方式與MyISAM截然不同。InnoDB的索引結構如下圖所示:

在上面索引結構的具體實現方式上有兩個區別,第一個區別在于InnoDB的數據文件本身就包含了索引部分。而從上文兩種存儲引擎區別的表格中可以知道,MyISAM索引和數據部分是分離的,索引文件僅保存的是數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域。例如,下圖為定義在Col3上的一個輔助索引示意圖:

了解InnoDB的索引實現后,就容易明白為什么不應該使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。再比如,用非單調的字段作為主鍵在InnoDB存儲引擎中并不是個好主意,因為InnoDB數據文件本身是一顆B+Tree,非單調的主鍵會造成在插入新記錄時數據文件為了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作為主鍵則是一個很好的選擇。

了解完上述內容,我們要進行mysql的優化,大致能做的就是:

合理安排資源、調整系統參數使MySQL運行更快、更節省資源。優化方面主要主要包括查詢、表設計、服務器等。最終要達到的效果是減少系統瓶頸,減少資源占用,增加系統的反應速度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696562.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696562.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696562.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【面試題】談談MySQL的事務

事務是啥 MySQL的事務就是把多個sql語句操作打包在一起執行,要么全部執行,要么一個都別執行。這種操作稱為“原子性”,是事務最核心的特征。當某個sql操作出錯時,就會進行“回滾/rollback”操作,即把執行過的操作逆向…

MySQL數據庫進階第二篇(索引,SQL性能分析,使用規則)

文章目錄 一、索引概述二、索引結構三、結構 - B-Tree四、結構 - BTree五、結構 - Hash六、索引分類七、索引語法1.案例代碼 八、SQL性能分析1.查看SQl執行頻率2.慢查詢日志3.PROFILES詳情4.EXPLAIN執行計劃 九、 索引使用規則十、SQL 提示十一、覆蓋索引十二、前綴索引十三、單…

滾動加載react-infinite-scroll-component

react-infinite-scroll-component 當請求數據量過大時,接口返回數據時間會很長,數據回顯時間長,Dom 的渲染會有很大的性能壓力。 antd的List組件中有提到一個滾動加載的組件庫react-infinite-scroll-component 實現滾動加載 Antd&#xff1…

考研高數(高階導數的計算)

1.歸納法 常見高階導數 2.泰勒展開式 3.萊布尼茲公式 4.用導數定義證明導函數在某一點連續的例題

【kubernetes】二進制部署k8s集群之cni網絡插件flannel和calico工作原理(中)

↑↑↑↑接上一篇繼續部署↑↑↑↑ 目錄 一、k8s集群的三種接口 二、k8s的三種網絡模式 1、pod內容器之間的通信 2、同一個node節點中pod之間通信 3、不同的node節點的pod之間通信 Overlay Network VXLAN 三、flannel網絡插件 1、flannel插件模式之UDP模式&#xff0…

java對象所占內存大小輸出

如何計算java對象所占內存大小&#xff0c;可以使用下述三種方法。 使用jdk8自帶API 使用下面語句打印對象所占內存大小&#xff1a;需要保證jdk版本是jdk8。System.out.println(ObjectSizeCalculator.getObjectSize(3L)); 借助org.apache.lucene工具類 引入maven坐標 <…

2024/2/22

P8680 [藍橋杯 2019 省 B] 特別數的和 題目描述 小明對數位中含有 2、0、1、9 的數字很感興趣&#xff08;不包括前導 00&#xff09;&#xff0c;在 1 到 40 中這樣的數包括 1、2、9、10 至 32、39 和 40&#xff0c;共28 個&#xff0c;他們的和是574。 請問&#xff0c;在…

【2024軟件測試面試必會技能】

Unittest(5)&#xff1a;unittest_忽略用例 忽略用例 在執行測試腳本的時候&#xff0c;可能會有某幾條用例本次不想執行&#xff0c;但又不想刪也 不想注釋&#xff0c;unittest通過忽略部分測試用例不執行的方式&#xff0c;分無條件忽略和有條 件忽略,通過裝飾器實現所描述…

Vue3+vite搭建基礎架構(11)--- 菜單欄功能和Tab頁功能實現

Vue3vite搭建基礎架構&#xff08;11&#xff09;--- 菜單欄功能和Tab頁功能實現 說明刪除項目中不需要的文件userStore全局屬性代碼菜單欄代碼Tab頁代碼解決瀏覽器輸入地址時不會打開tab頁問題和切換tab頁時參數丟失問題 說明 這里記錄下自己在Vue3vite的項目使用less來寫樣式…

低代碼開發——企業轉型的萬金油

在數字化時代&#xff0c;企業面臨著日新月異的市場環境和激烈的競爭壓力。為了在這場變革中脫穎而出&#xff0c;企業需要不斷優化業務流程、提升創新能力&#xff0c;以及實現敏捷響應。在這個過程中&#xff0c;低代碼開發作為一種創新性的技術手段&#xff0c;正成為企業轉…

統信UOS_麒麟KYLINOS上監控網絡:探索Smokeping的強大功能

原文鏈接&#xff1a;統信UOS|麒麟KYLINOS上監控網絡&#xff1a;探索Smokeping的強大功能 在當今的網絡環境中&#xff0c;無論是個人用戶還是企業用戶&#xff0c;都非常重視網絡的穩定性和連通性。特別是在進行遠程工作、在線會議、云計算等活動時&#xff0c;網絡質量直接影…

程序員必備技能----刪庫跑路大總結

刪庫跑路大總結&#xff0c;各個都是大殺器&#xff0c;破壞性太大&#xff0c;輕易不要嘗試。 刪除linux根目錄&#xff0c;用戶目錄&#xff0c;其實還可以增加一個刪除/etc。刪除&#xff08;清除&#xff09;數據庫。刪除redis緩存和持久化文件。刪除mongodb庫。git push …

說一說Eclipse的項目類型和常用項目的區別

Eclipse在新建項目的時候有很多類型&#xff0c;包括Java project、Web project等等&#xff0c;如下&#xff1a; 那么這些項目類型有什么區別呢&#xff1f;我們在創建項目的時候應該如何選擇&#xff0c;了解清楚這一點還是非常重要的&#xff0c;但記住一個出發點&#xff…

2.22 day3、4 QT

完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示"登錄成功”&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊Ok后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面 如果賬號和密碼不匹配&…

讀書筆記:《看電影學金融》

大空頭 禁止做空可以延緩資產價格下降的過程&#xff0c;但是人為保護的高股價最終還是不能持續的。做空引入的空頭買家&#xff0c;可以增加市場的流動性。住房價格指數期貨使房地產的投資屬性與住宅屬性分離&#xff0c;降低因炒房而空置的房屋&#xff0c;降低房價。收益互…

【論文解讀】Uncertainty Quantification of Collaborative Detection for Self-Driving

Uncertainty Quantification of Collaborative Detection for Self-Driving 摘要引言方法問題定義方法概覽Double-M 實驗結論 摘要 在聯網和自動駕駛汽車(CAVs)之間共享信息從根本上提高了自動駕駛協同目標檢測的性能。然而&#xff0c;由于實際挑戰&#xff0c;CAV 在目標檢測…

十九、圖像的放縮和插值

項目功能實現&#xff1a;對一張圖像進行放大和縮小操作 按照之前的博文結構來&#xff0c;這里就不在贅述了 一、頭文件 resizing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class RESIZING { public:void resizing(Mat& image); };#pragma…

深度解析:用 Python 爬蟲逆向破解 dappradar 的請求頭加密 X-Api-Sk

大家好!我是愛摸魚的小鴻,關注我,收看每期的編程干貨。 逆向是爬蟲工程師進階必備技能,當我們遇到一個問題時可能會有多種解決途徑,而如何做出最高效的抉擇又需要經驗的積累。本期文章將以實戰的方式,帶你詳細地逆向分析 dappradar 網站請求頭加密字段 X-Api-SK 的構造邏…

解決Edge瀏覽器,微博無法查看大圖(Edge Image Viewer)

使用Edge瀏覽器瀏覽微博或其它帶校驗的圖片時&#xff0c;會導致無法查看。 主要原因為Edge自帶了一個Edge Image Viewer, 但是該圖片查看器無法查看帶校驗數據的圖片&#xff0c;所以導致查看時一片空白。 解決方法 地址欄輸入 edge://flags/搜索 Edge Image Viewer選擇 Disa…