天天看點

MySQL · 特性分析 · common table expression

目前支援cte的資料庫有teradata, db2, firebird, microsoft sql server, oracle (with recursion since 11g release 2), postgresql (since 8.4), mariadb (since 10.2), sqlite (since 3.8.3), hypersql and h2 (experimental), mysql8.0.

cte的文法如下:

non-recursive ctes

MySQL · 特性分析 · common table expression

recursive ctes

MySQL · 特性分析 · common table expression

cte使語句更加簡潔

例如以下兩個語句表達的是同一語義,使用cte比未使用cte的嵌套查詢更簡潔明了。

1) 使用嵌套子查詢

2) 使用cte

cte 可以進行樹形查詢

MySQL · 特性分析 · common table expression

初始化這顆樹

1) 層序周遊

2) 深度優先周遊

oracle recursive with 語句不需要指定recursive關鍵字,可以自動識别是否recursive.

oracle 還支援cte相關的hint,

“materialize”告訴優化器産生一個全局的臨時表儲存結果,多次引用cte時直接通路臨時表即可。而”inline”則表示每次需要解析查詢cte。

postgresql從8.4開始支援cte,postgresql還擴充了cte的功能, cte的query中支援dml語句,例如

mariadb從10.2開始支援cte。10.2.1 支援non-recursive cte, 10.2.2開始支援recursive cte。 目前的ga的版本是10.1.

mysql從8.0開始支援完整的cte。mysql8.0還在development

階段,rc都沒有,ga還需時日。

alisql基于mariadb10.2, port了no-recursive cte的實作,此功能近期會上線。

以下從源碼主要相關函數簡要介紹其實作,

//解析識别with table引用

find_table_def_in_with_clauses

//檢查依賴關系,比如不能重複定義with table名字

with_clause::check_dependencies

// 為每個引用clone一份定義

with_element::clone_parsed_spec

//替換with table指定的列名

with_element::rename_columns_of_derived_unit

此實作對于多次引用cte,cte會解析多次,是以此版本cte有簡化sql的作用,但效率上沒有效提高。

以下是mysql8.0 隻掃描一次的執行計劃

以下是postgresql9.4 隻掃描一次的執行計劃

alisql還有待改進。

繼續閱讀