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 查询性能问题的主要内容,如果未能解决你的问题,请参考以下文章

提高 Postgresql 查询性能

提高 PostgreSQL 查询性能

PostgreSQL自动提交SELECT查询的效率

Postgresql COALESCE 性能问题

使用 SELECT 语句查询自定义 postgresql 参数

PostgreSQL 性能,使用 ILIKE 仅占两个百分比而不是根本不使用