PostgreSQL 函數(shù)優(yōu)化信息

2021-09-03 14:25 更新

默認(rèn)情況下,函數(shù)只是一個(gè)black box,數(shù)據(jù)庫(kù)系統(tǒng)對(duì)它的行為了解得很少。 不過(guò),這意味著使用函數(shù)的查詢執(zhí)行效率可能會(huì)低于它們的能力??梢蕴峁╊~外的知識(shí)幫助計(jì)劃器優(yōu)化函數(shù)調(diào)用。

一些基本事實(shí)可以通過(guò)CREATE FUNCTION命令中提供的聲明性注釋來(lái)提供。 這里面最重要的是函數(shù)的volatility category ( IMMUTABLESTABLEVOLATILE);在定義函數(shù)時(shí),要始終小心地正確指定這個(gè)。 并行安全屬性(PARALLEL UNSAFE、PARALLEL RESTRICTEDPARALLEL SAFE)也必須被指定,如果你希望在并行查詢中使用該函數(shù)。 指定函數(shù)的估算執(zhí)行開(kāi)銷也會(huì)有作用,和/或集返回函數(shù)估計(jì)返回的行數(shù)。不過(guò),指定這兩個(gè)事實(shí)的聲明方式只允許指定常數(shù)值,而這通常是不夠的。

也可以將一個(gè)planner support function 附加到SQL-可調(diào)用函數(shù)(稱為target function), 從而提供關(guān)于目標(biāo)函數(shù)的知識(shí),該函數(shù)過(guò)于復(fù)雜而無(wú)法以聲明方式表示。 計(jì)劃器支持函數(shù)必須寫(xiě)在 C 中(盡管它們的目標(biāo)函數(shù)可以不是),所以這是一個(gè)高級(jí)功能,相對(duì)很少有人會(huì)使用。

計(jì)劃器支持函數(shù)必須具有SQL簽名

supportfn(internal) returns internal

當(dāng)建立目標(biāo)函數(shù)時(shí),它通過(guò)指定SUPPORT子句附加到它的目標(biāo)函數(shù)。

計(jì)劃器支持函數(shù)的 API 的詳細(xì)信息可以在 PostgreSQL源代碼中的src/include/nodes/supportnodes.h文件中找到。 這里我們提供了計(jì)劃器支持函數(shù)的概述。支持函數(shù)的可能請(qǐng)求集合是可擴(kuò)展的,所以在將來(lái)的版本中可能會(huì)有更多(功能)。

在規(guī)劃期間,根據(jù)指定函數(shù)的特性,一些函數(shù)調(diào)用可以進(jìn)行簡(jiǎn)化。 例如,int4mul(n, 1)可以被簡(jiǎn)化為n。 這種類型的轉(zhuǎn)換可以通過(guò)計(jì)劃器支持函數(shù)執(zhí)行,通過(guò)它實(shí)現(xiàn)SupportRequestSimplify請(qǐng)求類型。 對(duì)于在查詢解析樹(shù)中找到其目標(biāo)函數(shù)的每個(gè)實(shí)例,將調(diào)用支持函數(shù)。如果它發(fā)現(xiàn)特定的調(diào)用可以簡(jiǎn)化成某種其他窗體,它可以構(gòu)建并返回表示該表達(dá)式的解析樹(shù)。 這將為基于函數(shù)的操作符自動(dòng)工作,非常—在剛才的示例中,n * 1也將簡(jiǎn)化為n。 (但注意這只是一個(gè)例子;這個(gè)特殊的優(yōu)化實(shí)際上不是標(biāo)準(zhǔn)的PostgreSQL執(zhí)行)。 我們不保證PostgreSQL在支持函數(shù)能夠簡(jiǎn)化的情況下,永遠(yuǎn)不會(huì)調(diào)用目標(biāo)函數(shù)。 確保簡(jiǎn)化表達(dá)式與目標(biāo)函數(shù)的實(shí)際執(zhí)行之間嚴(yán)格等效。

對(duì)于返回 boolean 的目標(biāo)函數(shù),估計(jì)使用該函數(shù)的 WHERE 子句將選擇的行的比重通常會(huì)有用。 這可以通過(guò)實(shí)現(xiàn)SupportRequestSelectivity請(qǐng)求類型的支持函數(shù)來(lái)完成。

如果目標(biāo)函數(shù)的運(yùn)行時(shí)間高度依賴于其輸入,提供非固定開(kāi)銷估算可能很有用。這可以通過(guò)實(shí)現(xiàn)SupportRequestCost請(qǐng)求類型的支持函數(shù)來(lái)完成。

對(duì)于返回集的目標(biāo)函數(shù),為提供要返回的行數(shù)的非常量估計(jì)通常很有用。這可以通過(guò)實(shí)現(xiàn)SupportRequestRows請(qǐng)求類型的支持函數(shù)來(lái)完成。

對(duì)于返回 boolean的目標(biāo)函數(shù),可以將WHERE中出現(xiàn)的函數(shù)調(diào)用轉(zhuǎn)換為一個(gè)可索引操作符子句或多個(gè)子句。 轉(zhuǎn)換的子句可能與函數(shù)的條件完全相同,或者它們可能比較弱態(tài)一些(也就是說(shuō),它們可能接受函數(shù)條件所不接受的一些值)。 在后一種情況下,索引條件被稱作lossy;它仍然可用于掃描索引,但必須為索引返回的每一行執(zhí)行函數(shù)調(diào)用,以看它是否真的通過(guò) WHERE條件或沒(méi)有。 要建立這樣的條件,支持函數(shù)必須實(shí)現(xiàn)SupportRequestIndexCondition需求類型。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)