我的应用程序中有一个查询,当我的表中有大量行时,它运行得非常快。但是当行数是中等大小(既不大也不小)时 - 相同的查询运行速度要慢15倍。
解释计划显示对中型数据集的查询使用嵌套循环作为其连接算法。大数据集使用散列连接。
我可以阻止查询规划器在数据库级别(postgresql.conf)或每个会话(SET enable_nestloop TO off
)使用嵌套循环。
set enable_nestloop to off
的潜在缺陷是什么?
其他信息:PostgreSQL 8.2.6,在Windows上运行。
答案 0 :(得分:8)
将
enable_nestloop
设置为off
会有什么潜在的陷阱?
这意味着您永远无法有效地使用索引。
似乎你现在不使用它们。
这样的查询:
SELECT u.name, p.name
FROM users u
JOIN profiles p ON p.id = u.profile_id
WHERE u.id = :id
如果您在这些字段上构建了索引,那么最有可能NESTED LOOPS
INDEX SCAN
user.id
INDEX SCAN
和profile.id
10%
。{ / p>
具有低选择性过滤器的查询(即,需要超过MERGE JOINS
来自其所使用的表的数据的查询)将受益于HASH JOINS
和NESTED LOOPS
。
但是上面给出的查询需要{{1}}才能有效运行。
如果您在此处发布查询和表定义,可能会对索引和查询性能做很多工作。
答案 1 :(得分:4)
在采取如此激烈措施之前需要考虑的一些事项:
将您的安装升级到最新的8.2.x(现在是8.2.12)。更好 - 考虑升级到下一个稳定版本8.3(8.3.6)。
考虑将您的生产平台更改为Windows以外的其他平台。 PostgreSQL的Windows端口虽然对于开发目的非常有用,但仍然与Un * x不同。
阅读“Planner Method Configuration”的第一段。这wiki page也可能会有所帮助。
答案 2 :(得分:2)
我有完全相同的经历。使用嵌套循环执行大型数据库上的一些查询,耗时12小时!关闭嵌套循环或删除索引时,它在30秒内运行。
这里有提示会很好,但我试过了
...
SET ENABLE_NESTLOOP TO FALSE;
... critical query
SET ENABLE_NESTLOOP TO TRUE;
...
处理此事。所以你绝对可以禁用和重新启用嵌套循环使用,你不能争论速度提高9000倍:))
我遇到的一个问题是在PgSQL / PL过程中更改ENABLE_NESTLOOP。我可以在Aqua Data Studio中运行一个SQL脚本,但是当我把它放在PgSQL / PL程序中时,它仍需要12个小时。显然它忽略了这一变化。