Postgresql
是否為每一行評估非動態標量子查詢?
一個獨立於父查詢(不引用父表)的標量子查詢是否只評估一次,或者對於每一行,不管?
SELECT /* ... */ FROM t1 WHERE parent = ( -- is this sq evaluated once? SELECT t2.id FROM t2 WHERE t2.id = 10 )
或使用 CTE
WITH parent_id AS ( SELECT t2.id FROM t2 WHERE t2.id = 10 ) SELECT /* ... */ WHERE parent = ( SELECT p.id FROM parent_id p -- is this sq evaluated once? )
如果答案是針對每一行評估子查詢/CTE,那麼在每一行上加入 CTE 會提高性能嗎?
WITH parent_id AS ( SELECT t2.id FROM t2 WHERE t2.id = 10 ) SELECT /* ... */ FROM t1, parent_id WHERE parent = parent_id.id
另外,有沒有辦法從
EXPLAIN ANALYZE
表達式被評估的次數中計算出來?注意:範例是任意的,並不反映真實場景,因此忽略這樣一個事實,即執行子查詢來找出
id
已知的 (10
) 是沒有意義的。
它被評估一次。
EXPLAIN ANALYZE
將顯示如下行:... InitPlan 1 (returns $0) -> Index Scan using t2_pkey on t2 (cost=0.29..5.31 rows=1 width=4) (actual time=0.024..0.025 rows=1 loops=1) Index Cond: (id = 10) ...
loops=1
告訴您子計劃只評估過一次。手冊:在某些查詢計劃中,可能會多次執行子計劃節點。例如,在上面的嵌套循環計劃中,每個外部行都會執行一次內部索引掃描。在這種情況下,該
loops
值報告節點的執行總數,$$ … $$
使用相關的子查詢,例如:
SELECT *, (SELECT id FROM t2 WHERE id = t1.parent_id) AS t2_id FROM t1;
(或更有用的東西)你會看到
loops=
n
,*n
*行數在哪裡t1
。