PostgreSQL查询缓慢避免使用函数

时间:2019-05-06 13:27:44

标签: sql postgresql indexing query-optimization

https://planchecker.cfapps.io/plan/Edo2MMbv

EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON) 
SELECT COUNT(*) AS "__count" 
FROM "juliet" 
WHERE ("juliet"."whiskey" IN ('F') AND "juliet"."three" <= '2001-04-30')

此字段juliet.three有一个索引,如何确定该查询使用该索引?

假设表有10N行,此查询返回3N行,因此计算了大表的30%。

威士忌酒是一个枚举字段,保留为没有索引的charfield。也许这是问题所在,但我不确定问题出在字符字段还是日期字段。

表的大小约为数百万。

我也收到这样的警告: WARNING: Filter using function | Check if function can be avoided

如何避免使用功能?有可能吗?

3 个答案:

答案 0 :(得分:2)

Postgres具有出色的优化程序,并根据其了解的信息和内置于数据库优化程序中的规则来选择最优化的执行计划。对于此查询,最佳索引在juliet(whiskey, three)上。

这是查询的覆盖索引,因此不需要访问数据行。另外,只需要扫描索引的30%。

没有正确的索引,强制进行索引扫描是没有意义的。

答案 1 :(得分:1)

如果查询确实返回了表的30%,则PostgreSQL使用顺序扫描时可能会选择最快的访问路径。

您可以尝试

SET enable_seqscan = off;

,然后再次运行查询以查看是否可以使用索引以及索引扫描实际上是否会更快。

答案 2 :(得分:1)

读取300万行的查询预计会很慢。我认为这是针对脱机流程的,因为将其用于在线应用程序正在寻找麻烦。

尽管@LaurenAlbe所说的是可能的,但我认为强行使用索引实际上可能会使您的查询比使用顺序扫描慢。

我只能看到@GordonLinoff所说的索引用法:将其用于“覆盖索引”。

但是...为什么首先要使用索引?通常,使用顺序扫描可以有效地运行任何读取表行的5%以上的查询。