我們知道,目前通用的數據庫查詢語言是SQL語言(Structured Query Language)。SQL語言也是一種編譯型語言,需要SQL編譯器編譯後才能執行,但它與C、C++、Java等語言不同,SQL語言是一種非過程化語言,這意味着使用SQL進行操作的時候,你只需要指定你要達到什麼目的,而無需指明要怎樣達到目的。
既然用戶只需要解決“做什麼”的問題,那麼,“怎麼做”的問題正是本文要討論的問題。
優化器(Optimizer)
優化器也稱查詢優化器(Query Optimizer),它的主要工作是優化數據訪問,根據提交的SQL語句,綜合各種已有的信息(主要是系統編目表)來產生最優的可執行的訪問方案。
優化器在整個數據庫系統中佔據着至高無上的地位,它是數據庫性能的決定因素,是所有數據庫引擎中最重要的組件。
優化器的工作可以直觀的理解爲以下4個步驟:
接收並驗證SQL語句的語法語義;
分析環境並優化滿足SQL語句的方法;
創建計算機可讀指令來執行優化的SQL;
執行指令或存儲他們以便將來執行。
查詢過程
先來看看SQL語句的大致執行流程
語法分析(Parse Query)
SQL語句被提交給SQL編譯器,編譯器通過語法樹(Parse Tree)分析該語句,檢查其語法,如果存在語法錯誤,編譯器就停止處理並返回錯誤信息;如果不存在語法問題,編譯器會將SQL語句轉換爲可被優化器分析的邏輯查詢語句(關係代數語句),並據此創建該查詢的查詢圖模。
語義檢查(Check Semantics)
語法分析完成後,編譯器會根據查詢圖模型進行語義檢查(比如檢查語句中的數據類型是否與數據庫的表列的數據類型一致),語義檢查完成後也會將相關信息添加到查詢圖模型,包括參考約束,表檢查約束,觸發器,和視圖信息等。
查詢重寫(Rewrite Query)
如果SQL語句的語法語義都沒有問題,就可以正式進行查詢操作了。這是優化器進行查詢優化的開始階段,其目的是將提交的SQL語句優化成效率更高的形式。
這種優化可以是基於查詢成本的考慮,也可以是基於查詢規則的考慮,是基於關係代數語句進行的調整。舉一個直觀的例子:
考慮下面兩條SQL語句,查詢工齡爲5年的員工及其所享有的年終獎級別:
Select EMPLOYEE.Name, WELFARE.Bonus From EMPLOYEE, WELFARE Where EMPLOYEE.Seniority > 5 And EMPLOYEE.Seniority = WELFARE.Seniority ;Select EMPLOYEE.Name, WELFARE.Bonus From EMPLOYEE, WELFARE Where EMPLOYEE.Seniority > 5 And WELFARE.Seniority > 5 And EMPLOYEE.Seniority = WELFARE.Seniority ;123
很顯然,兩條語句的功能相同,第二條後面的“WELFARE.Seniority > 5”條件還有點多餘,那麼,那條語句的執行效率更高?
答案是第二條!因爲第一條將EMPLOYEE中Seniority>5的行與WELFARE中的所有行作外連接再來找Seniority相等的行,而第二條則是將EMPLOYEE中Seniority>5的行和WELFARE中Seniority>5的行作外連接再來找Seniority相等的行。顯然,第二條語句只有更少的行參與外連接,效率自然更高。
可是,我們通常寫出的查詢語句都是第一條的形式,而查詢重寫卻可以將之優化,優化器的查詢重寫器能自動幫我們完成查詢語句的優化,找到更高效的查詢形式。
當然了,查詢重寫並不是直接對SQL語句作上述例子那樣的優化,它操作的是由語法分析轉換過的關係代數語句,且需要根據重寫圖模型提供的信息作出形式優化。
優化訪問計劃(Optimizer Access Plan)
根據查詢圖模型提供的信息,優化器會生成許多能夠滿足查詢請求的訪問計劃(執行方案方案),然後優化器綜合系統編目表中關於表,索引,列和函數等等的統計信息,估計每種訪問計劃的執行成本,並選擇具有最小成本的方案作爲最終的訪問計劃(Acess Plan)。
生成可執行代碼(Generate Executable Code)
根據最終選定的訪問計劃生成執行代碼,類似C語言編譯後生成可被機器識別的機器碼一樣。
執行訪問計劃(Execute Plan)
執行可執行代碼,獲取查詢結果集。
轉載:https://blog.csdn.net/u013007900/article/details/78015124