1

我有一个简单的选择查询:

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。

4

1 回答 1

1

您希望 100 个最小的 entity_id 符合您的条件。现在 - 如果这些是数字 1..100 那么显然使用 entity_id 索引是处理这个问题的最佳方法 - 一切都是预先排序的。事实上,如果你想要的 100 在 1..200 范围内,那么它仍然是有意义的。大概 1..1000 会。

所以 - PostgreSQL 认为它会在表的“开始”处找到很多 entity_type_id=1 值。它估计按类型过滤然后排序的成本为 8134 与 26231。在你的情况下,这是错误的。

现在 - 要么存在一些不明显的相关性(这很糟糕 - 我们目前无法告诉计划者),要么我们没有最新或足够的统计数据。

ANALYZE entities什么不同吗?您可以通过阅读手册中的 planner-stats 页面来了解规划者所知道的值。

于 2013-11-13T14:22:09.433 回答