PostgreSql Select 查询性能问题
Posted
技术标签:
【中文标题】PostgreSql Select 查询性能问题【英文标题】:PostgreSql Select query performance issue 【发布时间】:2013-11-13 07:27:36 【问题描述】:我有一个简单的选择查询:
SELECT * FROM entities WHERE entity_type_id = 1 ORDER BY entity_id
然后我想得到前100个结果,所以我用这个:
SELECT * FROM entities WHERE entity_type_id = 1 ORDER BY entity_id LIMIT 100
问题是第二个查询比第一个查询慢得多。执行第一个查询不到一秒,执行第二个查询则超过一分钟。
这些是查询的执行计划:
无限制:
Sort (cost=26201.43..26231.42 rows=11994 width=72)
Sort Key: entity_id
-> Index Scan using entity_type_id_idx on entities (cost=0.00..24895.34 rows=11994 width=72)
Index Cond: (entity_type_id = 1)
有限制:
Limit (cost=0.00..8134.39 rows=100 width=72)
-> Index Scan using xpkentities on entities (cost=0.00..975638.85 rows=11994 width=72)
Filter: (entity_type_id = 1)
我不明白为什么这两个计划如此不同,为什么性能下降这么多。我应该如何调整第二个查询以使其更快地工作?
我使用 PostgreSql 9.2。
【问题讨论】:
entity_id 是主键还是有索引? entity_id 是主键,entity_type_id 上有索引 那么你就不需要order by了,因为它已经默认按照entity_id升序排序了。 如果我不使用 order by,我会得到不同的结果。 @Kuzgun - 别傻了。在您指定“排序依据”之前,不会对任何内容进行排序。 【参考方案1】:您希望 100 个最小的 entity_id 符合您的条件。现在 - 如果那些是数字 1..100 那么显然使用 entity_id 索引是处理这个问题的最佳方法 - 一切都是预先排序的。事实上,如果你想要的 100 在 1..200 范围内,那么它仍然是有意义的。大概 1..1000 会。
所以 - PostgreSQL 认为它会在表的“开始”处找到许多 entity_type_id=1 值。它估计按类型过滤然后排序的成本为 8134 与 26231。你的情况是错误的。
现在 - 要么存在一些不明显的相关性(这很糟糕 - 我们目前无法告诉规划者),要么我们没有最新或足够的统计数据。
ANALYZE entities
有什么不同吗?您可以通过阅读planner-stats page in the manuals 了解规划者所了解的价值观。
【讨论】:
以上是关于PostgreSql Select 查询性能问题的主要内容,如果未能解决你的问题,请参考以下文章