【问题标题】:Why is Postgres not using my index on a simple ORDER BY LIMIT 1?为什么 Postgres 不在简单的 ORDER BY LIMIT 1 上使用我的索引?
【发布时间】:2017-03-14 21:20:08
【问题描述】:

我有一个大表(大约 11,000,000 行),我需要找到给定排序条件的第一项。

请注意,Date 列 NOT 接受空值

为什么 Postgres 不使用索引:

CREATE INDEX track_ix_date
  ON "Track"
  USING btree
  ("Date" DESC NULLS LAST);

关于这个简单的查询:

select * from "Track" order by "Date" desc limit 1

但它确实在其他查询中使用它:

select * from "Track" order by "Date" desc nulls last limit 1

第二个查询实际上比第一个查询快得多。

我已阅读indexes and ORDER BY 文档并说在带有LIMIT 子句的ORDER BY 的特殊情况下,使用索引而不是扫描表更有效,因为排序需要扫描完整的表只是为了得到一个项目

Postgres 不应该检测到 nulls last / first 无关紧要,因为该列不接受空值并且只使用最快的方法吗?

【问题讨论】:

  • 如果您知道您的DATE 列是NOT NULL,为什么还要指定NULLS LAST?
  • 因为我注意到索引扫描使用条件DATE IS NOT NULL,所以我把NULLS LAST 认为postgre 正在检查该条件,因为当以降序排序时,第一个元素被认为是可能为空
  • 请edit您的问题并添加使用explain (analyze, verbose)生成的执行计划。 Formatted 文本 请no screen shots

标签: postgresql indexing sql-order-by


【解决方案1】:

因为您正在对该查询执行“SELECT ALL ROWS”。 Postgres 不需要使用索引。

我敢打赌,如果您添加了“WHERE date = ?”条件,将使用索引。

【讨论】:

  • 不,即使我们添加where date = ?,它也没有使用索引
【解决方案2】:

总有一个权衡,因为让优化器更智能也意味着让优化器变慢,这会伤害到每个人。

目前,它还不够智能,因此您必须更改索引定义或查询才能使其正常工作。

可能值得在 pgsql-hackers 邮件列表上请求这样的改进,或者自己为它编写一个补丁并在那里提交。

【讨论】:

    猜你喜欢
    • 2013-09-20
    • 2014-03-17
    • 1970-01-01
    • 2012-10-07
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多