【问题标题】:PostgreSql Select query performance issuePostgreSql Select 查询性能问题
【发布时间】: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 - 别傻了。在您指定“排序依据”之前,不会对任何内容进行排序。

标签: sql postgresql query-optimization


【解决方案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 了解规划者所了解的价值观。

【讨论】:

    猜你喜欢
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多