需要運行查詢以查看至少存在一條記錄的位置。所以這個問題: 「什麼是更有效」:PERFORM * vs PERFORM 1
PERFORM * FROM table
或
PERFORM 1 FROM table
爲什麼呢?
需要運行查詢以查看至少存在一條記錄的位置。所以這個問題: 「什麼是更有效」:PERFORM * vs PERFORM 1
PERFORM * FROM table
或
PERFORM 1 FROM table
爲什麼呢?
需要注意的是,首先,PERFORM
不是SQL指令,它是plpgsql
關鍵字,它指示解釋器運行等效的SELECT,然後丟棄結果。
每文檔(Executing a Command With No Result):
PERFORM查詢;
這將執行查詢並丟棄結果。以與編寫SQL SELECT命令相同的方式編寫查詢 ,但用PERFORM替換關鍵字SELECT的初始 。對於WITH查詢,請使用PERFORM,然後使用 將查詢放在括號中。 (在這種情況下,只有 查詢返回一行)。PL/pgSQL變量將替換爲查詢 ,就像不返回結果的命令一樣,並且計劃以相同方式緩存在 中。此外,特殊的變量FOUND設置爲true,如果 查詢產生至少一行,還是假的,如果沒有生成行
所以現在的問題是一樣的:你是怎麼SELECT * FROM table
和SELECT 1 FROM table
比較檢查桌子上至少有一排?但問題在於,它們在性能方面都不夠好,而且如果桌子上有很多排,實際上它們顯得很不合適。
讓我們在一個真實的例子測試了最新的PostgreSQL 9.3有兩個大表:
words(int,text)
(3。4000000線和文本列總是很小)inverted_word_index(int,int,bytea,int)
(約10萬線,所述BYTEA是平均寬和2kB的最大400個字節)查詢重複幾個連續次數與予保持只有最快的執行與psql的\timing on
測試1的第一個表
從字上執行1:
mlists=> do $$ begin perform 1 from words; end; $$; DO Time: 521,379 ms
執行*從文字:
mlists=> do $$ begin perform * from words; end; $$; DO Time: 442,800 ms
結果1:此表上,perform *
似乎一直有點快於perform 1
。
測試2與第2臺
PERFORM 1從inverted_word_index:
mlists=> do $$ begin perform 1 from inverted_word_index ; end; $$; DO Time: 2206,230 ms
執行*從inverted_word_index:
mlists=> do $$ begin perform * from inverted_word_index ; end; $$; DO Time: 16848,971 ms
結果2:此表的最執行perform *
比最好的執行者慢得多perform 1
,所以這與之前的結果相反。
結論:沒有一般的贏家,它似乎取決於表內容。
但真正有趣的一點是,兩種方法全面掃描表而不是停在第一行,所以它們都太慢了。
相當快的方法:
mlists=> do $$ begin perform 1 from words limit 1; end; $$; DO Time: 0,330 ms mlists=> do $$ begin perform * from words limit 1; end; $$; DO Time: 0,405 ms mlists=> do $$ begin perform 1 from inverted_word_index limit 1; end; $$; DO Time: 0,333 ms mlists=> do $$ begin perform * from inverted_word_index limit 1; end; $$; DO Time: 0,314 ms
重複執行表明,這兩種結構的持續時間0.3毫秒,0.4毫秒,沒有勝者之間變化。速度差很小,以至於不相關的動態因素。
我不知道爲什麼你想放棄結果。
個人我最好使用沿的線的東西:
select count(*)
into rows_exist
from (select * from my_table limit 1) t;
單行用的0或1的值是保證被返回,並且僅在表中的單個行中的順序被讀出要做到這一點。
至於「1」與「*」 - 我的直覺是說優化器足夠智能,只讀取所需的列以回答查詢。
但是,如果您運行explain with (verbose true)它表明所有列都從子查詢投影。如果是這種情況,那麼使用「select *」的效率會更低,特別是如果從表的開頭刪除了大量的行,並且使用「select *」會導致許多塊被全部讀取發現第一個之前的表掃描。我歡迎來自PostgreSQL內部專家的意見,看看這是否是對計劃的正確解釋。
這不完全是我的問題。有你的例子,我會問,是否SELECT *優於SELECT 1? – Macchiatow
你也可以看看測試'PERFORM FROM'。如果你打算使用特殊變量FOUND,不需要'*'或'1'。 – Daniel
@Daniel:沒有列的'SELECT'或'PERFORM'是PostgreSQL 9.5之前的語法錯誤 –