Postgresql

是否為每一行評估非動態標量子查詢?

  • April 14, 2018

一個獨立於父查詢(不引用父表)的標量子查詢是否只評估一次,或者對於每一行,不管?

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

引用自:https://dba.stackexchange.com/questions/203952