溫故知新-Mysql的體系結構概覽&sql優化步驟



Mysql的體系結構概覽

Mysql的體系結構概覽
整個MySQL Server由以下組成

  • Connection Pool : 連接池組件
  • Management Services & Utilities : 管理服務和工具組件
  • SQL Interface : SQL接口組件
  • Parser : 查詢分析器組件
  • Optimizer : 優化器組件
  • Caches & Buffers : 緩衝池組件
  • Pluggable Storage Engines : 存儲引擎
  • File System : 文件系統

連接層

最上層是一些客戶端和鏈接服務,包含本地sock 通信和大多數基於客戶端/服務端工具實現的類似於 TCP/IP的通信。主要完成一些類似於連接處理、授權認證、及相關的安全方案。在該層上引入了線程池的概念,爲通過認證安全接入的客戶端提供線程。同樣在該層上可以實現基於SSL的安全鏈接。服務器也會爲安全接入的每個客戶端驗證它所具有的操作權限

服務層

第二層架構主要完成大多數的核心服務功能,如SQL接口,並完成緩存的查詢,SQL的分析和優化,部分內置函數的執行。所有跨存儲引擎的功能也在這一層實現,如 過程、函數等。在該層,服務器會解析查詢並創建相應的內部解析樹,並對其完成相應的優化如確定表的查詢的順序,是否利用索引等, 最後生成相應的執行操作。如果是select語句,服務器還會查詢內部的緩存,如果緩存空間足夠大,這樣在解決大量讀操作的環境中能夠很好的提升系統的性能。

引擎層

存儲引擎層, 存儲引擎真正的負責了MySQL中數據的存儲和提取,服務器通過API和存儲引擎進行通信。不同的存儲引擎具有不同的功能,這樣我們可以根據自己的需要,來選取合適的存儲引擎。

存儲層

數據存儲層, 主要是將數據存儲在文件系統之上,並完成與存儲引擎的交互。

和其他數據庫相比,MySQL有點與衆不同,它的架構可以在多種不同場景中應用併發揮良好作用。主要體現在存儲引擎上,插件式的存儲引擎架構,將查詢處理和其他的系統任務以及數據的存儲提取分離。這種架構可以根據業務的需求和實際需要選擇合適的存儲引擎。

存儲引擎

存儲引擎概述

  • 和大多數的數據庫不同, MySQL中有一個存儲引擎的概念, 針對不同的存儲需求可以選擇最優的存儲引擎。存儲引擎就是存儲數據,建立索引,更新查詢數據等等技術的實現方式 。存儲引擎是基於表的,而不是基於庫的。所以存儲引擎也可被稱爲表類型。
  • Oracle,SqlServer等數據庫只有一種存儲引擎。MySQL提供了插件式的存儲引擎架構。所以MySQL存在多種存儲引擎,可以根據需要使用相應引擎,或者編寫存儲引擎。
  • MySQL5.0支持的存儲引擎包含 : InnoDB 、MyISAM 、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、
    ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事務安全表,其他存儲引擎是非事務安
    全表。

可以通過指定 show engines , 來查詢當前數據庫支持的存儲引擎 :
存儲引擎

存儲引擎特性存儲引擎特性對比

InnoDB

InnoDB存儲引擎是Mysql的默認存儲引擎。InnoDB存儲引擎提供了具有提交、回滾、崩潰恢復能力的事務安全。
但是對比MyISAM的存儲引擎,InnoDB寫的處理效率差一些,並且會佔用更多的磁盤空間以保留數據和索引。
InnoDB存儲引擎不同於其他存儲引擎的特點 :

  • 事務控制
  • 外鍵約束
  • 存儲方式

    InnoDB 存儲表和索引有以下兩種方式 :
    ①. 使用共享表空間存儲, 這種方式創建的表的表結構保存在.frm文件中, 數據和索引保存在
    innodb_data_home_dir 和 innodb_data_file_path定義的表空間中,可以是多個文件。
    ②. 使用多表空間存儲, 這種方式創建的表的表結構仍然存在 .frm 文件中,但是每個表的數據和索引單獨保存在
    .ibd 中

MyISAM

MyISAM 不支持事務、也不支持外鍵,其優勢是訪問的速度快,對事務的完整性沒有要求或者以SELECT、INSERT
爲主的應用基本上都可以使用這個引擎來創建表 。

MEMORY

  • 基本上不用;

MERGE

  • 基本上不用;

存儲引擎的選擇

在選擇存儲引擎時,應該根據應用系統的特點選擇合適的存儲引擎。對於複雜的應用系統,還可以根據實際情況選
擇多種存儲引擎進行組合。以下是幾種常用的存儲引擎的使用環境。

  • InnoDB : 是Mysql的默認存儲引擎,用於事務處理應用程序,支持外鍵。如果應用對事務的完整性有比較高的要求,在併發條件下要求數據的一致性,數據操作除了插入和查詢意外,還包含很多的更新、刪除操作,那麼InnoDB存儲引擎是比較合適的選擇。InnoDB存儲引擎除了有效的降低由於刪除和更新導致的鎖定, 還可以確保事務的完整提交和回滾,對於類似於計費系統或者財務系統等對數據準確性要求比較高的系統,InnoDB是最合適的選擇。
  • MyISAM : 如果應用是以讀操作和插入操作爲主,只有很少的更新和刪除操作,並且對事務的完整性、併發性要求不是很高,那麼選擇這個存儲引擎是非常合適的。

優化SQL步驟

定位低效率執行SQL

show processlist : 慢查詢日誌在查詢結束以後才紀錄,所以在應用反映執行效率出現問題的時候查詢慢查詢日誌並不能定位問題,可以使用show processlist命令查看當前MySQL在進行的線程,包括線程的狀態、是否鎖表等,可以實時地查看 SQL 的執行情況,同時對一些鎖表操作進行優化。

explain分析執行計劃

  • 通過以上步驟查詢到效率低的 SQL 語句後,可以通過 EXPLAIN或者 DESC命令獲取 MySQL如何執行 SELECT 語句的信息,包括在 SELECT 語句執行過程中表如何連接和連接的順序
  • eg: EXPLAIN SELECT * FROM t_note_info WHERE content_id = 350419
    test
    explain

id

id 字段是 select查詢的序列號,是一組數字,表示的是查詢中執行select子句或者是操作表的順序。id 情況有三種

  • id 相同表示加載表的順序是從上到下。
  • id 不同id值越大,優先級越高,越先被執行。
  • id 有相同,也有不同,同時存在。id相同的可以認爲是一組,從上往下順序執行;在所有的組中,id的值越大,優先級越高,越先執行。

select_type

  • 表示 SELECT 的類型,常見的取值,如下表所示:
    select_type

select_type

  • 展示這一行的數據是關於哪一張表的

type

  • type 顯示的是訪問類型,是較爲重要的一個指標,可取值爲:
  • 需要保證查詢至少達到 range 級別, 最好達到ref 。
    type

key & key_len

  • possible_keys : 顯示可能應用在這張表的索引, 一個或多個。
  • key : 實際使用的索引, 如果爲NULL, 則沒有使用索引。
  • key_len : 表示索引中使用的字節數, 該值爲索引字段最大可能長度,並非實際使用長度,在不損失精確性的前
    提下, 長度越短越好 。

rows

  • 掃描行的數量。

extra

  • 其他的額外的執行計劃信息,在該列展示 。
    在這裏插入圖片描述

合理的使用索引

  • 索引是數據庫優化最常用也是最重要的手段之一, 通過索引通常可以幫助用戶解決大多數的MySQL的性能優化問題。

避免索引失效

  • 最左前綴法則

    如果符合最左法則,但是出現跳躍某一列,只有最左列索引生效:

  • 範圍查詢右邊的列,不能使用索引

  • 不要在索引列上進行運算操作,索引將失效

  • 字符串不加單引號,造成索引失效

    在查詢時如果沒有對字符串加單引號,MySQL的查詢優化器,會自動的進行類型轉換,造成索引失效。

  • 儘量使用覆蓋索引,避免select *

    即:只訪問索引的查詢(索引列完全包含查詢列)),減少select * ,在上一篇中我們頁提到原因快速理解-mysql索引結構&頁&聚集索引&非聚集索
    InnoDB主鍵索引的葉子節點存放的是整行數據,非主鍵索引的葉子節點存放的是主鍵的值,SQL只需要通過索引就可以返回查詢所需要的數據,而不必通過二級索引查到主鍵之後再去查詢數據。
    當然在執行計劃中的體現在extra字短中:
    using index :使用覆蓋索引的時候就會出現
    using where:在查找使用索引的情況下,需要回表去查詢所需的數據
    using index condition:查找使用了索引,但是需要回表查詢數據
    using index ; using where:查找使用了索引,但是需要的數據都在索引列中能找到,所以不需要回表查詢數據

  • 用or分割開的條件, 如果or前的條件中的列有索引,而後面的列中沒有索引,那麼涉及的索引都不會被用到。

  • 以%開頭的Like模糊查詢,索引失效。

如果僅僅是尾部模糊匹配,索引不會失效。如果是頭部模糊匹配,索引失效。
可以通過覆蓋索引來解決,但最好不要這麼做

  • 如果MySQL評估使用索引比全表更慢,則不使用索引。
  • is NULL , is NOT NULL 有時索引失效
  • in 走索引, not in 索引失效
  • 儘量使用複合索引,而少使用單列索引
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章