为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

弑天下 2019-10-26 12:48:13
如果Postgres坚持执行顺序扫描,该如何迫使它使用索引?
查看完整描述

3 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

假设您要查询许多数据库中常见的“索引提示”功能,PostgreSQL没有提供这种功能。这是PostgreSQL团队做出的明智决定。在这里可以找到关于为什么以及可以做什么的很好的概述。究其原因,基本上是因为它是一个性能黑客,随着数据的变化,它会在以后引起更多的问题,而PostgreSQL的优化器可以根据统计信息对计划进行重新评估。换句话说,今天可能是一个好的查询计划,可能永远不会成为一个好的查询计划,并且索引提示会一直强迫一个特定的查询计划。


您可以使用enable_seqscan和enable_indexscan参数,这是一个非常钝的锤子,对于测试非常有用。看到:


检查索引用法

enable_ 参数

这些不适合正在进行的生产使用。如果您在选择查询计划时遇到问题,则应查看有关跟踪查询性能问题的文档。不要只是设置enable_参数并走开。


除非您有充分的理由使用索引,否则Postgres可能会做出正确的选择。为什么?


对于小型表,顺序扫描更快。

当数据类型不正确匹配时,Postgres不使用索引,您可能需要包括适当的转换。

您的计划程序设置可能会引起问题。


查看完整回答
反对 回复 2019-10-26
?
慕娘9325324

TA贡献1783条经验 获得超4个赞

可能是使用的唯一有效理由


set enable_seqscan=false

是在编写查询并希望快速查看表中有大量数据时查询计划的实际情况。或者,当然,如果您只是因为数据集太小而需要快速确认查询未使用索引的话。


查看完整回答
反对 回复 2019-10-26
?
慕村9548890

TA贡献1884条经验 获得超4个赞

有时PostgreSQL无法针对特定条件对索引进行最佳选择。例如,假设有一个包含几百万行的事务处理表,其中每天有数百行,并且该表具有四个索引: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可能选择使用索引transactions_description_idx而不是transactions_date_idx,这可能导致查询花费几分钟而不是不到一秒钟的时间。在这种情况下,您可以通过以下条件强制使用日期索引:


SELECT client_id, SUM(amount)

FROM transactions

WHERE date >= 'yesterday'::timestamp AND date < 'today'::timestamp AND

      description||'' = 'Refund'

GROUP BY client_id


查看完整回答
反对 回复 2019-10-26
  • 3 回答
  • 0 关注
  • 7349 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信