防止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在查詢的慢版本之前,它運行得非常快,但我理解一般來說,使用這種設置是個壞主意。.例如,我是否可以創建一個特定的索引,以使查詢計劃者更有可能選擇明顯更有效的策略?有人能提出為什么PostgreSQL的查詢規劃器會為其中一個查詢選擇這么糟糕的策略嗎?下面我已經包含了可能有幫助的模式的細節。
防止PostgreSQL有時選擇錯誤的查詢計劃
婷婷同學_
2019-07-12 15:25:14