Postgresql

為什麼這個隱式連接的計劃與顯式連接不同?

  • March 15, 2017

在這個答案中,我解釋了 SQL-89 的隱式語法。

但是我在玩的時候注意到了不同的查詢計劃:

EXPLAIN ANALYZE
 SELECT *
 FROM (values(1)) AS t(x), (values(2)) AS g(y);

                                    QUERY PLAN                                     
------------------------------------------------------------------------------------
Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
Planning time: 0.052 ms
Execution time: 0.020 ms
(3 rows)

與此相反:

EXPLAIN ANALYZE
 SELECT *
 FROM (values(1)) AS t(x)                      
 CROSS JOIN (values(2)) AS g(y);
                                          QUERY PLAN                                           
------------------------------------------------------------------------------------------------
Subquery Scan on g  (cost=0.00..0.02 rows=1 width=4) (actual time=0.004..0.005 rows=1 loops=1)
  ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
Planning time: 0.075 ms
Execution time: 0.027 ms
(4 rows)

**為什麼其中一個會出現Subquery Scan

隱式語法不只是重寫為與顯式語法相同嗎?**

隱式語法不只是重寫為與顯式語法相同嗎?

不必要。你建立在稍微不正確的假設之上。就像我在引用的問題下解釋的那樣:

列表中逗號分隔的項目與顯式****表示法FROM幾乎相同,但並不完全相同CROSS JOIN。顯式連接綁定更強。在某些情況下,查詢規劃器必須以不同方式處理這兩種情況。

顯然,計劃器足夠聰明,能夠VALUES用簡化的計劃來處理帶有單行表達式的表達式。VALUES我們在表達式中看到了一個針對多行的更複雜的計劃:

EXPLAIN ANALYZE
SELECT *
FROM  (VALUES (1), (2)) t(x)
   , (VALUES (2), (3)) g(y);
 Nested Loop  (cost=0.00..0.11 rows=4 width=8) (actual time=0.059..0.064 rows=4 loops=1)
   ->  Values Scan on "*VALUES*"  (cost=0.00..0.03 rows=2 width=4) (actual time=0.004..0.004 rows=2 loops=1)
   ->  Materialize  (cost=0.00..0.04 rows=2 width=4) (actual time=0.025..0.026 rows=2 loops=2)
         ->  Values Scan on "*VALUES*_1"  (cost=0.00..0.03 rows=2 width=4) (actual time=0.001..0.002 rows=2 loops=1)

VALUES對於用逗號分隔的表達式,簡化查詢計劃更容易。當被顯式連接綁定時,Postgres 需要在與其他逗號分隔的項目組合之前考慮連接條件。FROM我希望我們在這種情況下看到的“subqery 掃描”是這種情況下更複雜的程式碼路徑的(完全無害的)副作用。

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