PostgreSQL實現了SQL Standard2011的大部分內容,SQL處理是數據庫中非常復雜的一部分內容。
本文簡要介紹了SQL處理的相關內容。
簡要介紹
SQL文的處理分為以下幾個部分:
- Parser階段(詞法分析,語法解析)
對應於source中的parser模塊 - analyzer階段(語義分析)
對應於source中的analyzer模塊
內部處理中將Parser階段生成的Parser tree轉換為Query tree - rewriter階段(查詢重寫)
安裝規則系統進行查詢重寫,還有視圖重新
對應於source中的rewriter模塊 - Planner階段(生成最優查詢計划)
對應於source中planner模塊 - Executor階段(查詢計划執行)
對應於source中executor模塊
上圖顯示了SQL文處理的5個階段。
Parser階段
利用flex,bison等工具進行語法和語義分析,最終生成Parser tree。
輸入:SQL文
輸出:Parser tree
以下圖為例,介紹下parser tree長什么樣子
根據上圖可以清晰的看到select的列對應於parser tree的target list
select 文的from部分對應於parser tree的from clause
select 文的where部分對應於parser tree的where clause
select文的order by部分對應於parser tree的sort clause
analyzer階段
對於parser階段的生成parser tree進行語義分析,生成Query tree
輸入:Parser tree
輸出:Query tree
以下圖為例,介紹下Query tree長什么樣子
targetlist 是select文的查詢結果的list。以上圖為例select文查詢的列有兩個id和data,則targetlist有兩個元素,每個元素對應於一個TargetEntry。
rtable表示范圍表range table,是所有表的list。
jointree 存儲了from clause和where clause。
rewriter階段
根據pg_rule系統catalog中的規則將改變Query tree。
輸入:Query tree
輸出:Query tree
以視圖為例
sampledb=# CREATE VIEW employees_list
sampledb-# AS SELECT e.id, e.name, d.name AS department
sampledb-# FROM employees AS e, departments AS d WHERE e.department_id = d.id;
sampledb=# SELECT * FROM employees_list
根據上圖所示,Querytree中范圍表rtable中的內容進行了轉變。
Planner
根據rewriter階段的Query tree生成最優查詢計划樹Plan tree,然后通過執行器executor進行執行。
PostgreSQL中Plan tree可以通過EXPLAIN命令進行顯示
testdb=# EXPLAIN SELECT * FROM tbl_a WHERE id < 300 ORDER BY data;
QUERY PLAN
---------------------------------------------------------------
Sort (cost=182.34..183.09 rows=300 width=8)
Sort Key: data
-> Seq Scan on tbl_a (cost=0.00..170.00 rows=300 width=8)
Filter: (id < 300)
(4 rows)
下圖顯示了Plan tree和EXPLAIN執行結果的關系
plan tree的類型有很多種,上圖中是SortNode類型,source文件 plannodes.h中定義了所有的類型。
執行器在執行時先從Plan tree的底部開始執行,最后到頂部。
以上圖為例,先對table_a進行順序掃描,然后再進行排序獲得最終結果。
Executor
執行器執行plan tree的過程中,通過buffer manager進行table和index的讀寫。執行時也需要一些內存比如:temp_buffers, work_mem,包括一些臨時文件。
此外在存取元組時,PostgreSQL會用到mvcc機制保證並發時事務的一致性和隔離性