MySQL中一條SQL是如何執行的?

MySQL簡介

MySQL是一個關係型數據庫管理系統,由瑞典MySQL AB 公司開發,屬於 Oracle 旗下產品。由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇 MySQL 作爲數據庫

近年來,隨着MySQL的不斷髮展,越來越多的互聯網公司也選擇了MySQ作爲數據庫存儲,其中不乏一些大廠,說明MySQL越來越受開發者的青睞

MySQL體系結構

MySQL體系結構

  • Connectors組件提供對外的連接,供JDBC、ODBC、PHP、 Python等進行數據庫連接
  • 連接池組件(Connection Pool) 負責接收外部請求,將請求轉發到對應的模塊,每個連接成功的請求都會分配一個線程來負責維護客戶端與MySQL服務器的連接,該線程負責接收客戶端的請求,返回結果給客戶端
  • 管理服務和工具組件(Management Service & Utilities)負責MySQL服務端的管理,如備份、恢復、安全、配置等
  • SQL接口組件(SQL Interface) 負責處理DML、DDL、存儲過程、觸發器等SQL操作,並返回結果
  • 查詢分析器組件(Parser) 分析SQL(檢查語法、合法性)
  • 優化器組件(Optimizer) 優化SQL命令進行標準的優化分析
  • 緩衝組件(Caches & Buffers) 用於查詢數據的緩衝和緩存
  • 插件式存儲引擎(Pluggable Storage Engines) MySQL特有的特性,提供了各種類型的存儲引擎用於不同的業務場景
  • 物理文件(File System) 存儲MySQL 數據庫文件、日誌文件、redo日誌、Undo日誌、索引等文件

MySQL區別於其他數據庫最重要的一個特點就是插件式存儲引擎

存儲引擎是底層物理結構的實現,每個存儲引擎開發者可以按照自己的意願來進行開發

存儲引擎是基於表的,而不是數據庫。也就是同一個庫中的不同表可以採用不同的存儲引擎

存儲引擎的好處是,每個存儲引擎都有各自的特點,能夠根據具體的應用建立不同存儲引擎表

MySQL存儲引擎

由於MySQL數據庫開源特性,產生了很多種不同的存儲引擎,下面來介紹幾種常用的存儲引擎

InnoDB存儲引擎

InnoDB存儲引擎支持事務,其設計目標主要面向在線事務處理(OLTP)的應用

其特點是行鎖設計、支持外鍵,並支持類似於Oracle的非鎖定讀,即默認讀取操作不會產生鎖

從MySQL數據庫5.5.8版本開始,InnoDB存儲引擎是默認的存儲引擎

InnoDB通過使用多版本併發控制(MVCC)來獲得高併發性,並且實現了SQL標準的4種隔離級別,默認爲REPEATABLE級別。同時,使

用一種被稱爲next-key locking的策略來避免幻讀(phantom)現象的產生。除此之外,InnoDB儲存引擎還提供了插入緩衝(insert buffer)、二次寫(double write)、自適應哈希索引(adaptive hash index)、預讀(read ahead)等高性能和高可用的功能

實際工作中,InnoDB應該是用的最多的存儲引擎

MyISAM存儲引擎

MyISAM存儲引擎不支持事務、表鎖設計,支持全文索引,主要面向一些OLAP數據庫應用

在MySQL 5.5.8版本之前MyISAM存儲引擎是默認的存儲引擎(除Windows版本外),5.5.8以後默認存儲引擎就換成InnoDB

MyISAM存儲引擎表由MYD和MYI組成,MYD用來存放數據文件,MYI用來存放索引文件

注意 對於MyISAM存儲引擎表,MySQL數據庫只緩存其索引文件,數據文件的緩存交由操作系統本身來完成,這與其他使用LRU算法緩存

數據的大部分數據庫大不相同。此外,在MySQL 5.1.23版本之前,無論是在32位還是64位操作系統環境下,緩存索引的緩衝區最大隻能設

置爲4GB。在之後的版本中,64位系統可以支持大於4GB的索引緩衝區

NDB存儲引擎

NDB存儲引擎是一個集羣存儲引擎,類似於Oracle的RAC集羣,不過與Oracle RAC share everything架構不同的是,其結構是

sharenothing的集羣架構,因此能提供更高的可用性

NDB的特點是數據全部放在內存中(從MySQL 5.1版本開始,可以將非索引數據放在磁盤上),因此主鍵查找(primary key lookups)的

速度極快,並且通過添加NDB數據存儲節點(Data Node)可以線性地提高數據庫性能,是高可用、高性能的集羣系統

關於NDB存儲引擎,有一個問題值得注意,那就是NDB存儲引擎的連接操作(JOIN)是在MySQL數據庫層完成的,而不是在存儲引擎層完

成的。這意味着,複雜的連接操作需要巨大的網絡開銷,因此查詢速度很慢

Memory存儲引擎

Memory存儲引擎(之前稱HEAP存儲引擎)將表中的數據存放在內存中,如果數據庫重啓或發生崩潰,表中的數據都將消失。它非常適合

用於存儲臨時數據的臨時表,以及數據倉庫中的緯度表。Memory存儲引擎默認使用哈希索引,而不是我們熟悉的B+樹索引

雖然Memory存儲引擎速度非常快,但在使用上還是有一定的限制。比如,只支持表鎖,併發性能較差,並且不支持TEXT和BLOB列類型。

最重要的是,存儲變長字段(varchar)時是按照定常字段(char)的方式進行的,因此會浪費內存

Archive存儲引擎

Archive存儲引擎只支持INSERT和SELECT操作,從MySQL 5.1開始支持索引。Archive存儲引擎使用zlib算法將數據行(row)進行壓縮後

存儲,壓縮比一般可達1∶10。正如其名字所示,Archive存儲引擎非常適合存儲歸檔數據,如日誌信息。Archive存儲引擎使用行鎖來實現

高併發的插入操作,但是其本身並不是事務安全的存儲引擎,其設計目標主要是提供高速的插入和壓縮功能

Federated存儲引擎

Federated存儲引擎表並不存放數據,它只是指向一臺遠程MySQL數據庫服務器上的表。這非常類似於SQL Server的鏈接服務器和Oracle

的透明網關,不同的是,當前Federated存儲引擎只支持MySQL數據庫表,不支持異構數據庫表。

Maria存儲引擎

Maria存儲引擎是新開發的引擎,設計目標主要是用來取代原有的MyISAM存儲引擎,從而成爲MySQL的默認存儲引擎

Maria存儲引擎的特點是:支持緩存數據和索引文件,應用了行鎖設計,提供了MVCC功能,支持事務和非事務安全的選項,以及更好的

BLOB字符類型的處理性能

SQL是如何執行的

一條查詢的SQL發送到MySQL服務器被執行,返回查詢結果,這中間經歷了什麼?下面我們來看一下一條SQL語句從客戶端發

送給MySQL服務器,MySQL到底執行了哪些操作?

在這裏插入圖片描述

如上圖所示,

  • 客戶端SQL發送到MySQL服務端,首先會去查詢緩存裏面查找,如果多次執行同一個SQL是會命中緩存中,此時直接通過緩存來取數據
  • 若沒有命中查詢緩存,則將SQL發送給解析器,解析器會對SQL過行語法、語義分析,同時也會對SQL合法性進行校驗
  • SQL語義解析出來後,優化器會對SQL語義進行優化,比如,是走索引還是全表掃描,優化器會根據實際情況來確定一個最優的執行方案(當然,不一定是最優的,只是給出MySQL認爲是最優的執行方案)
  • 優化完畢後,就給到執行器進行執行SQL,取出SQL執行結果
  • 最後將執行結果返回給客戶端

簡單歸納一下,一條SQL在MySQL中的執行過程如下:
SQL ==> 查詢緩存 ==> 解析器 ==> 優化器 ==> 執行器

當然,實際的過程遠遠比這個要複雜,這裏只是列出來大致的步驟和過程,方便大家理解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章