防止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的查询规划器会为其中一个查询选择这么糟糕的策略吗?下面我已经包含了可能有帮助的模式的细节。
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 关注
- 699 浏览
添加回答
举报
0/150
提交
取消