防止PostgreSQL有時選擇錯誤的查詢計劃對于使用PostgreSQL 8.4.9進行查詢的PostgreSQL性能,我遇到了一個奇怪的問題。此查詢是在3D卷中選擇一組點,使用LEFT OUTER JOIN若要添加存在關聯ID的相關ID列,請執行以下操作。的小變化x范圍會導致PostgreSQL選擇不同的查詢計劃,執行時間從0.01秒到50秒不等。這是一個有問題的查詢:SELECT treenode.id AS id,
treenode.parent_id AS parentid,
(treenode.location).x AS x,
(treenode.location).y AS y,
(treenode.location).z AS z,
treenode.confidence AS confidence,
treenode.user_id AS user_id,
treenode.radius AS radius,
((treenode.location).z - 50) AS z_diff,
treenode_class_instance.class_instance_id AS skeleton_id FROM treenode LEFT OUTER JOIN
(treenode_class_instance INNER JOIN
class_instance ON treenode_class_instance.class_instance_id
= class_instance.id
AND class_instance.class_id = 7828307)
ON (treenode_class_instance.treenode_id = treenode.id
AND treenode_class_instance.relation_id = 7828321)
WHERE treenode.project_id = 4
AND (treenode.location).x >= 8000
AND (treenode.location).x <= (8000 + 4736)
AND (treenode.location).y >= 22244
AND (treenode.location).y <= (22244 + 3248)
AND (treenode.location).z >= 0
AND (treenode.location).z <= 100
ORDER BY parentid DESC, id, z_diff
LIMIT 400;我不是解析這些查詢計劃的專家,但明顯的區別似乎在于x它使用的范圍是Hash Left Join為LEFT OUTER JOIN(這非???,而對于另一個范圍,它使用的是Nested Loop Left Join(這似乎很慢)。在這兩種情況下,查詢都返回大約90行。如果我做了SET ENABLE_NESTLOOP TO FALSE在查詢的慢版本之前,它運行得非??欤依斫庖话銇碚f,使用這種設置是個壞主意。.例如,我是否可以創建一個特定的索引,以使查詢計劃者更有可能選擇明顯更有效的策略?有人能提出為什么PostgreSQL的查詢規劃器會為其中一個查詢選擇這么糟糕的策略嗎?下面我已經包含了可能有幫助的模式的細節。
3 回答

慕標5832272
TA貢獻1966條經驗 獲得超4個贊
1. 統計是不準確的。
ANALYZE
VACUUM ANALYZE
ANALYZE
(前兩個答案仍然適用于Postgres 9.6。)
default_statistics_target
WHERE
JOIN
ALTER TABLE ... ALTER COLUMN ... SET STATISTICS 400; -- calibrate number
目標可以設定在0到10000之間;
ANALYZE
2. 成本設置對規劃師來說,估計值已經取消了。

慕森卡
TA貢獻1806條經驗 獲得超8個贊
ORDER BY parentid DESC, id, z_diff
parentid DESC, id, z
- 3 回答
- 0 關注
- 740 瀏覽
添加回答
舉報
0/150
提交
取消