W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
要了解規(guī)則系統(tǒng)是如何工作的,必須要知道它什么時(shí)候被調(diào)用以及它的輸入和結(jié)果是什么。
規(guī)則系統(tǒng)位于解析器和規(guī)劃器之間。它采用解析器的輸出(即一個(gè)查詢樹)和用戶定義的重寫規(guī)則(也是查詢樹,不過帶有一些額外信息),并且常見零個(gè)或者更多個(gè)查詢樹作為結(jié)果。因此它的輸入和輸出總是那些規(guī)劃器自身就能產(chǎn)生的東西,并且因此它看到的任何東西都可以被表示成一個(gè)SQL語句。
那么什么是一個(gè)查詢樹?它是一個(gè)SQL語句的一種內(nèi)部表示,其中用于創(chuàng)建它的每一個(gè)單獨(dú)的部分都被獨(dú)立存儲。如果你設(shè)置了配置參數(shù)debug_print_parse
、debug_print_rewritten
或debug_print_plan
,這些查詢樹可以被顯示在服務(wù)器日志中。規(guī)則動作也被做為查詢樹存儲在系統(tǒng)目錄
pg_rewrite
中。它們沒有被格式化為日志輸出的形式,但是它們包含完全相同的信息。
閱讀一棵未加工的查詢樹需要要一些經(jīng)驗(yàn)。但是由于查詢樹的SQL表示形式足以用來理解規(guī)則系統(tǒng),本章將不會教授如何閱讀查詢樹。
在閱讀本章中查詢樹的SQL表現(xiàn)形式時(shí),讀者需要能夠知道語句被分解成了哪些部分并且能在查詢樹結(jié)構(gòu)中標(biāo)識它們。一棵查詢樹的部分有:
這是一個(gè)簡單的值來說明是哪一種命令(SELECT
、INSERT
、UPDATE
、DELETE
)產(chǎn)生了該查詢樹。
范圍表是被使用在該查詢中的關(guān)系的列表。在一個(gè)SELECT
語句中,范圍表是在關(guān)鍵詞FROM
后面給出的關(guān)系。
每一個(gè)范圍表項(xiàng)標(biāo)識一個(gè)表或視圖,并且說明在該查詢的其他部分要以哪個(gè)名稱調(diào)用它。在查詢樹中,范圍表項(xiàng)被使用編號而不是名稱來引用,因此在一個(gè)SQL語句中出現(xiàn)重復(fù)的名字也沒有關(guān)系。在規(guī)則的范圍表被合并以后可能會發(fā)生這種情況。本章中的例子將不會有這種情況。
這是一個(gè)指向范圍表的索引,它標(biāo)識了該查詢的結(jié)果應(yīng)該去哪個(gè)關(guān)系。
SELECT
查詢沒有結(jié)果關(guān)系(特殊情況SELECT INTO
幾乎等于CREATE TABLE
后面跟上INSERT ... SELECT
,并且不在這里單獨(dú)討論)。
對于INSERT
、UPDATE
和DELETE
命令,結(jié)果關(guān)系是修改要進(jìn)行的表(或視圖!)。
目標(biāo)列表是一個(gè)表達(dá)式的列表,它定義了查詢的結(jié)果。在一個(gè)SELECT
的情況下,這些表達(dá)式會構(gòu)建出該查詢最終的輸出。它們對應(yīng)于關(guān)鍵字SELECT
和FROM
之間的表達(dá)式(*
是一個(gè)關(guān)系所有列名的縮寫。解析器會把它擴(kuò)展成獨(dú)立的列,因此規(guī)則系統(tǒng)永遠(yuǎn)見不到它)。
DELETE
命令不需要一個(gè)目標(biāo)列表,因?yàn)樗鼈儾划a(chǎn)生任何結(jié)果。相反,規(guī)劃器會向空的目標(biāo)列表中加入一個(gè)特殊的CTID項(xiàng)來允許執(zhí)行器找到要被刪除的行(當(dāng)結(jié)果關(guān)系是一個(gè)普通表時(shí)才加入CTID。如果結(jié)果關(guān)系是一個(gè)視圖,則會被規(guī)則系統(tǒng)加入一個(gè)整行變量,如第 40.2.4 節(jié)所述)。
對于INSERT
命令,目標(biāo)列表描述了將要進(jìn)入到結(jié)果關(guān)系中的新行。它由VALUES
子句中的表達(dá)式或來自INSERT ... SELECT
中SELECT
子句的表達(dá)式構(gòu)成。重寫處理的第一步會為那些沒有被原始命令賦值但有默認(rèn)值的列增加目標(biāo)列項(xiàng)。任何剩余的列(既沒有給定值也沒有默認(rèn)值)將被規(guī)劃器用一個(gè)常量空值表達(dá)式填充。
對于UPDATE
命令,目標(biāo)列表描述要替換舊行的新行。在規(guī)則系統(tǒng)中,它只包含來自命令的SET column = expression
部分的表達(dá)式。規(guī)劃器將處理缺失的列,做法是為它們插入表達(dá)式,這種表達(dá)式會把舊行的值復(fù)制到新行。正如DELETE
一樣,會增加一個(gè)CTID或整行變量,這樣執(zhí)行器能夠標(biāo)識要被更新的舊行。
目標(biāo)列表中的每一個(gè)項(xiàng)所包含的表達(dá)式可以是一個(gè)常量值、一個(gè)指向范圍表中關(guān)系的列的變量、一個(gè)參數(shù)或一個(gè)由函數(shù)調(diào)用、常量、變量、操作符等構(gòu)成的表達(dá)式樹。
查詢的條件是一個(gè)表達(dá)式,它很像包含在目標(biāo)列表項(xiàng)中的表達(dá)式。這個(gè)表達(dá)式的結(jié)果值是一個(gè)布爾值,它說明對最終結(jié)果行的操作(INSERT
、UPDATE
、DELETE
或SELECT
)是否應(yīng)該被執(zhí)行。它對應(yīng)于一個(gè)SQL語句的
WHERE
子句。
查詢的連接樹展示了FROM
子句的結(jié)構(gòu)。對于一個(gè)SELECT ... FROM a, b, c
這樣的簡單查詢,連接樹就是FROM
項(xiàng)的一個(gè)列表,因?yàn)槲覀儽辉试S以任何順序連接它們。但是當(dāng)JOIN
表達(dá)式(特別是外連接)被使用時(shí),我們必須按照連接顯示的順序來連接。在這種情況下,連接樹展示了
JOIN
表達(dá)式的結(jié)構(gòu)。與特定JOIN
子句(來自ON
或USING
)相關(guān)的限制被存儲為附加到那些連接樹節(jié)點(diǎn)的條件表達(dá)式。我們發(fā)現(xiàn)把頂層WHERE
表達(dá)式存儲為附加到頂層連接樹項(xiàng)的一個(gè)條件也很方便。這樣實(shí)際上連接樹表達(dá)了一個(gè)SELECT
的
FROM
和WHERE
子句。
查詢樹的其他部分(如ORDER BY
子句)在這里并不受到關(guān)注。規(guī)則系統(tǒng)在應(yīng)用規(guī)則時(shí)會替換這里的某些項(xiàng),但是這些與規(guī)則系統(tǒng)的基礎(chǔ)沒有什么關(guān)系。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: