T-SQL執行內幕(3)——解析和編譯
本文屬於SQL Server T-SQL執行內幕系列
接上文,當請求被任務接收同時得到工作執行緒指派執行後,就開始在SQL Server內部進行運作。當請求被執行時,第一步就是要先解析(Parsing)請求,把TDS資料流轉換成SQL Server可識別的格式。
從客戶端傳送的是T-SQL文字,然後轉換成TDS資料流,到達SQL Server之後變回T-SQL文字。但是由於純T-SQL文字是“類英語的宣告式語言”,SQL Server仍舊無法理解,需要再次解析為一種叫抽象語法樹(
如果這個階段出現錯誤,整個請求就會終止。此時請求和任務標識為完成狀態,對應的worker被釋放然後用於執行其他pending的任務。
如果解析成功之後,就進行編譯(compilation)操作。
SQL語言(不僅T-SQL)可以具有很複雜的語句,如大量JOIN等。同時SQL並非接近機器指令的語言,所以不是類似CLI指令或JVM位元組碼這類可執行程式碼,要執行SQL命令,實際上是使用資料訪問計劃(data access plans,
關於解析和編譯,常見的問題在於SQL過於複雜或者不正確使用動態查詢條件。從而使得解析過程異常困難並且導致後續的步驟主要是優化非常不準確。關於這部分的介紹可以看本人的系列文章(http://blog.csdn.net/dba_huangzj/article/details/49928527
在完成解析和編譯之後,生成一個編譯樹,傳到優化器中進行優化。
總結
解析和繫結是查詢提交到SQL Server後的第一個操作,編譯確保T-SQL查詢是符合語法的,然後轉換成原始的樹結構(邏輯樹),但是這個樹結構依舊是表達語句的相對高階的表現。相對於源語句,邏輯樹可以表達“從xx表中讀取資料”、“進行inner join”這樣的含義。但是在這個過程中邏輯樹可以接收不同的名字。
繫結實際上是名稱解析,用於對邏輯樹進行檢查,確保所有物件名都存在,所有關聯的表及其列名都能在系統目錄檢視中存在。在繫結之後,就生成代數樹並傳入查詢優化器中。