MS SQL Query的內部運作
要解開SQL 效能的謎題,首先先讓我們看看 SQL Server 內部的運作,
對一個資料庫而言不管是 SQL Server or MSSQL,都會有類似的架構與運作方式,
主要的負責人
先讓我們看看圖中幾個主要的負責人
- SNI (Server Network Interface): 主要負責SQL Server 與網路傳送接收資料
- Relation Engine:這個部分為資料庫的核心,解析所有SQL語法、運算最佳的查詢效率。
- Storage Engine: 主要決定資料的存取方式,到 memory 存取 or Disk ?
- Buffer Pool: SQL Server 記憶體中主要存放的快取內容為 data 與 Query plan
Query 的流程
了解主要幾個負責人之後,接著我們來看整個 SQL Query 執行的過程
1. Client 端送出SQL Query 透過 TDS (Tabular Data Stream)通訊協定送至 SQL Server
例如:Select name from tb_Name
2. SQL Server SNI 收到該指令,轉交由 command parser 處理,解析該指令與語法
3. Command Parser 轉交由 optimizer 計算怎樣的執行方式會比較有效率,
要透過 Index Scan or Index Seek,如果沒有 Index 要怎樣存取等。
根據資料的量、query 語法、Join table 、統計資訊等,相對計算出較便宜的cost 執行
Query Plan
4. 選出較便宜cost的 query plan 之後,交由 Query Executor 執行
5. SQL 執行時,Access Methods 會考量如何存取所要的資料,透過記憶體 or 到 Disk
6/7. Buffer Manager 會協助管理存取記憶體的資料內容,
如果記憶體已經有之前的資料或是query plan,
Buffer Manager會就直接由記憶體直接取用,否則就到磁碟存取
8/9/10. 接著,將取到的資料回傳,query Executor => SNI => 再透過SNI 網路傳輸至 client
這就是整個 Query 的流程. 這樣的流程跟資料庫效能有什麼關係呢?
舉幾個例子說明:
1. Query 是不是經常需要 re-compile ? 因為 recompile 會耗用 CPU 時間
2. Index 會間接影響 Query plan 與資料存取的方式,查詢的效率等
3. Select * …這樣的查詢會增加 SQL server 到磁碟存取的次數與 SNI與網路資料量的傳輸
4. Memory 的大小,會影響 data cache 與 plan cahce 是不是有效率.
對於電腦來說至 memory 存取的單位為 naro sec 而至磁碟的存取卻是 mili sec
或是由資源效能瓶頸來看的話,
CPU Pressure
有可能是 CPU privileged time 造成 > 因為 high Disk I/O > 因為 SQL server 找不到 memory cache 資料
也有可能是因為 query 的語法造成需要常常 re-compile
Memory Pressure
也有可能因為 page in/out 的次數很多 or 記憶體很小or 因為查詢語法造成 or Index 沒有效率等
Memory Pressure 可以從 Available Bytes, Page out, Page Life Expectancy 等
performance counters 中進一步觀察確定原因
結語
因此,SQL Server 效能瓶頸,比較難頭痛醫頭,腳痛醫腳
必須要全面性的評估,相對應的關係等
這也讓資料庫效能調教成為科學與藝術的結合
因為要做到恰到好處的平衡狀態,
並且要定期檢視與微調
才能讓資料庫運作更加順暢