任何人都可以解釋爲什麼PostgreSQL的工作這麼:PostgreSQL如何執行查詢?
如果我執行這個查詢
SELECT
*
FROM project_archive_doc as PAD, project_archive_doc as PAD2
WHERE
PAD.id = PAD2.id
這將是簡單JOIN
和EXPLAIN
會是這樣的:
Hash Join (cost=6.85..13.91 rows=171 width=150)
Hash Cond: (pad.id = pad2.id)
-> Seq Scan on project_archive_doc pad (cost=0.00..4.71 rows=171 width=75)
-> Hash (cost=4.71..4.71 rows=171 width=75)
-> Seq Scan on project_archive_doc pad2 (cost=0.00..4.71 rows=171 width=75)
但是,如果我將執行此查詢:
SELECT *
FROM project_archive_doc as PAD
WHERE
PAD.id = (
SELECT PAD2.id
FROM project_archive_doc as PAD2
WHERE
PAD2.project_id = PAD.project_id
ORDER BY PAD2.created_at
LIMIT 1)
不會有聯接和EXPLAIN
樣子:
Seq Scan on project_archive_doc pad (cost=0.00..886.22 rows=1 width=75)"
Filter: (id = (SubPlan 1))
SubPlan 1
-> Limit (cost=5.15..5.15 rows=1 width=8)
-> Sort (cost=5.15..5.15 rows=1 width=8)
Sort Key: pad2.created_at
-> Seq Scan on project_archive_doc pad2 (cost=0.00..5.14 rows=1 width=8)
Filter: (project_id = pad.project_id)
爲什麼是這樣,是否有關於這個的任何文件或物品?
附加where子句'PAD2.project_id = PAD.project_id'加上'LIMIT 1'使優化器相信很少的行將滿足條件(估計=一行),所以它選擇exaxtly提取這一行。如果桌子變大,情況可能會改變。那就是:計劃可能會改變,結果將永遠是一排。優化器(大部分)總是正確的... – joop
@joop,「結果將永遠是一行」你只談論子查詢嗎?因爲整個查詢返回多個行。 –
@DenisNikanorov這些查詢完全不同。你爲什麼要比較它們? –