Postgresql
為什麼這個隱式連接的計劃與顯式連接不同?
但是我在玩的時候注意到了不同的查詢計劃:
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 掃描”是這種情況下更複雜的程式碼路徑的(完全無害的)副作用。