我如何强制Postgres使用特定的索引?

如果强制Postgres使用索引,否则会坚持进行顺序扫描?

假设您在询问在许多数据库中发现的常见“索引暗示”function,PostgreSQL不提供这样的function。 这是PostgreSQL团队做出的有意识的决定。 在这里可以find一个很好的概述为什么,你可以做什么。 原因基本上就是,随着数据的变化,性能破坏会导致更多的问题,而PostgreSQL的优化器可以根据统计数据重新计算计划。 换句话说,今天什么可能是一个好的查询计划可能不会是一个好的查询计划,索引提示会一直强制执行一个特定的查询计划。

作为一个非常钝的锤子,可用于testing,您可以使用enable_seqscanenable_indexscan参数。 看到:

  • 检查索引使用情况
  • enable_参数

这些不适合正在进行的生产使用 。 如果您在查询计划select方面遇到问题,则应该查看用于跟踪查询性能问题的文档 。 不要只设置enable_ params然后走开。

除非你有足够的理由来使用这个索引,否则Postgres可能会做出正确的select。 为什么?

  • 对于小型表格,执行顺序扫描会更快。
  • 当数据types不匹配时Postgres不使用索引,您可能需要包含适当的强制转换。
  • 您的计划器设置可能会导致问题。

另请参阅这个旧的新闻组post 。

可能是唯一有效的使用原因

 set enable_seqscan=false 

是在编写查询时想要快速查看查询计划实际上是否存在大量表中的数据。 或者当然,如果您需要快速确认您的查询不使用索引,只是因为数据集太小。

这个问题本身是非常无效的。 强制(例如,通过执行enable_seqscan = off)是非常糟糕的主意。 检查是否会更快,但生产代码不应该使用这种技巧。

相反 – 解释你的查询分析,读取它,并找出为什么PostgreSQLselect不好(在你的意见)的计划。

有网上的工具,帮助阅读解释分析输出 – 其中之一是explain.depesz.com – 由我写的。

另一个select是在freenode ircnetworking上join#postgresql频道,并与那里的人交谈,以帮助你 – 因为优化查询不是“问一个问题,得到答案很高兴”的问题。 这更像是一个谈话,许多事情要检查,很多事情要学习。

有时候PostgreSQL没有针对特定条件做出索引的最佳select。 举个例子,假设有一个有几百万行的交易表,其中有几百个交易表,有四个索引:transaction_id,client_id,date和description。 您想要运行以下查询:

 SELECT client_id, SUM(amount) FROM transactions WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND description = 'Refund' GROUP BY client_id 

PostgreSQL可能select使用索引transactions_description_idx而不是transactions_date_idx,这可能导致查询花费几分钟而不是不到一秒。 如果是这样的话,你可以强制使用date指数来欺骗这样的条件:

 SELECT client_id, SUM(amount) FROM transactions WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND description||'' = 'Refund' GROUP BY client_id 

EnterpriseDB的PostgresPlus高级服务器产品支持Oracle提示语法,虽然该产品不是免费的。

有一个滴答推pushgres喜欢seqscan在子查询中添加一个OFFSET 0

当你实际只查找第n个/最后一个元素时,这对于优化连接大/大表的请求来说非常方便。

比方说,你正在寻找第一/最后20个元素涉及多个表有100K(或更多)的条目,没有build立/连接所有的数据查询所有的数据,当你要找的是前100或1000条目。 例如,在这种情况下,执行顺序扫描的速度要快10倍以上。

请参阅如何防止Postgres内联子查询?