?
This document uses PHP Chinese website manual Release
PREPARE name [ ( data_type [, ...] ) ] AS statement
PREPARE創(chuàng)建一個(gè)預(yù)備語(yǔ)句。一個(gè)預(yù)備語(yǔ)句是服務(wù)器端的對(duì)象,可以用于優(yōu)化性能。 在執(zhí)行PREPARE語(yǔ)句的時(shí)候,指定的查詢被分析、重寫、規(guī)劃。 當(dāng)隨后發(fā)出EXECUTE語(yǔ)句的時(shí)候,預(yù)備語(yǔ)句就只需要執(zhí)行了。 因此,分析、重寫、規(guī)劃階段都只執(zhí)行一次,而不是每次都要執(zhí)行一次。
預(yù)備語(yǔ)句可以接受參數(shù):在它執(zhí)行的時(shí)候替換到查詢中的數(shù)值。 可以在一個(gè)預(yù)備語(yǔ)句里按照位置來(lái)引用參數(shù),比如$1,$2等。 可以指定一個(gè)相應(yīng)的參數(shù)數(shù)據(jù)類型列表。 如果一個(gè)參數(shù)的數(shù)據(jù)類型沒(méi)有被指定或聲明為unknown, 那么其類型將根據(jù)該參數(shù)所使用的實(shí)際上下文環(huán)境進(jìn)行推測(cè)(如果有可能的話)。 當(dāng)執(zhí)行該語(yǔ)句的時(shí)候,將在EXECUTE語(yǔ)句中為這些參數(shù)指定實(shí)際值。 參見(jiàn)EXECUTE獲取更多信息。
預(yù)備語(yǔ)句只是在當(dāng)前數(shù)據(jù)庫(kù)會(huì)話的過(guò)程中存在。如果客戶端退出, 那么預(yù)備語(yǔ)句就會(huì)被遺忘,因此必須在被重新使用之前重新創(chuàng)建。 這也意味著一個(gè)預(yù)備語(yǔ)句不能被多個(gè)數(shù)據(jù)庫(kù)客戶端同時(shí)使用;但是, 每個(gè)客戶端可以創(chuàng)建它們自己的預(yù)備語(yǔ)句來(lái)使用。預(yù)備語(yǔ)句可以用 DEALLOCATE命令手工清除。
如果一個(gè)會(huì)話準(zhǔn)備用于執(zhí)行大量類似的查詢,那么預(yù)備語(yǔ)句可以獲得最大限度的性能優(yōu)勢(shì)。 如果查詢非常復(fù)雜,需要復(fù)雜的規(guī)劃或者重寫,那么性能差距將更加明顯。 比如,如果查詢?cè)O(shè)計(jì)許多表的連接,或者有多種規(guī)則要求應(yīng)用。如果查詢的規(guī)劃和重寫相對(duì)簡(jiǎn)單, 而執(zhí)行起來(lái)開(kāi)銷相當(dāng)大,那么預(yù)備語(yǔ)句的性能優(yōu)勢(shì)就不那么明顯。
給予這個(gè)特定的預(yù)備語(yǔ)句任意名字。它必須在一個(gè)會(huì)話中是唯一的,并且用于執(zhí)行或者刪除一個(gè)預(yù)備語(yǔ)句。
預(yù)備語(yǔ)句的某個(gè)參數(shù)的數(shù)據(jù)類型。如果某個(gè)參數(shù)的數(shù)據(jù)類型未指定或指定為unknown, 那么將根據(jù)該參數(shù)使用的上下文環(huán)境進(jìn)行推斷。可以使用 $1,$2等等在預(yù)備語(yǔ)句內(nèi)部引用這個(gè)參數(shù)。
SELECT,INSERT,UPDATE, DELETE或VALUES語(yǔ)句之一。
在一些情況下,PostgreSQL為一個(gè)預(yù)備語(yǔ)句生成的查詢 規(guī)劃可能還不如按照普通方法提交并執(zhí)行的查詢生成的規(guī)劃好。 這是因?yàn)樵摬樵冊(cè)诒灰?guī)劃的時(shí)候(也是優(yōu)化器判斷最優(yōu)查詢規(guī)劃的時(shí)候), 在查詢中聲明的任何參數(shù)的實(shí)際數(shù)值都還不可見(jiàn)。 PostgreSQL在表中收集數(shù)據(jù)分布的統(tǒng)計(jì),而且可以利用查 詢中的常量來(lái)猜測(cè)執(zhí)行查詢的可能結(jié)果。 因?yàn)檫@些數(shù)據(jù)在規(guī)劃的時(shí)候還是未知,所以,得到的規(guī)劃可能很差勁。 使用EXPLAIN查看PostgreSQL 為預(yù)備語(yǔ)句選取的查詢計(jì)劃。
有關(guān)查詢規(guī)劃和PostgreSQL為查詢優(yōu)化的目的收集統(tǒng)計(jì)的更多信息, 參閱ANALYZE文檔。
可以通過(guò)查詢pg_prepared_statements 系統(tǒng)試圖獲得某個(gè)會(huì)話中所有可用的預(yù)備語(yǔ)句
為一個(gè)INSERT語(yǔ)句創(chuàng)建一個(gè)預(yù)備語(yǔ)句然后執(zhí)行它:
PREPARE fooplan (int, text, bool, numeric) AS INSERT INTO foo VALUES($1, $2, $3, $4); EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
為一個(gè)SELECT語(yǔ)句創(chuàng)建一個(gè)預(yù)備語(yǔ)句然后執(zhí)行它:
PREPARE usrrptplan (int) AS SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid AND l.date = $2; EXECUTE usrrptplan(1, current_date);
注意,第二個(gè)參數(shù)的數(shù)據(jù)類型并未指定。所以將從上下文環(huán)境推測(cè)$2的類型。
SQL標(biāo)準(zhǔn)包含一個(gè)PREPARE語(yǔ)句,但是它只用于嵌入式SQL。 PostgreSQL實(shí)現(xiàn)的PREPARE語(yǔ)句的語(yǔ)法也略有不同。