gpt4 book ai didi

PostgreSQL 查询不使用索引

转载 作者:行者123 更新时间:2023-11-29 11:39:17 26 4
gpt4 key购买 nike

我有一个非常简单的数据库模式,它在以下列上有一个多列 b 树索引:

PersonId, Amount, Commission

现在,如果我尝试使用以下查询选择表:

explain select * from "Order" where "PersonId" = 2 AND "Commission" > 3

Pg 正在扫描索引并且查询非常快,但是如果我尝试以下查询:

explain select * from "Order" where "PersonId" > 2 AND "Commission" > 3

即使存在索引,它也会进行顺序扫描。即使是这个查询

explain select * from "Order" where "Commission" > 3 

进行顺序扫描。有人愿意解释为什么吗? :-)

非常感谢。

更新

该表包含 1 亿行。我创建它只是为了针对 MS SQL 测试 PostgreSQL 性能。该表已经被 VACUUMED。我正在运行 Core I5 2500k 四核 cpu 和 8 GB 内存。

下面是这个查询的解释分析结果:

explain ANALYZE select * from "Order" where "Commission" BETWEEN 3000000 AND 3000010  LIMIT 20 


Limit (cost=0.00..2218328.00 rows=1 width=24) (actual time=28043.249..28043.249 rows=0 loops=1)
-> Seq Scan on "Order" (cost=0.00..2218328.00 rows=1 width=24) (actual time=28043.247..28043.247 rows=0 loops=1)
Filter: (("Commission" >= 3000000::numeric) AND ("Commission" <= 3000010::numeric))
Total runtime: 28043.278 ms

最佳答案

简短的回答是,在比较各种可用计划时,根据您配置的成本因素和可用的最新统计数据,顺序扫描预计是最快的。从您提供的少量信息来看,规划者很可能做出了正确的选择。如果您有三个单列索引,它可能能够使用位图索引扫描,特别是当要选择的行少于表中行的大约 10% 时。

请注意,对于您描述的索引,需要扫描整个索引以查找 "PersonId"> 2 的所有行;除非您对 "PersonId" 有很多负值,否则它很可能是表的大部分内容。

另请注意,如果您有一个很小的表——比如几千行或更少,通过索引访问这些行很少会比仅扫描那几行更快。计划对数据量很敏感,您获得的行数少的计划与您获得的行数多的计划不太可能相同。

如果实际上没有选择最快的计划,则很有可能需要调整成本因素以更好地模拟机器上的成本。另一种可能性是您需要更积极地设置 autovacuum,以确保提供最新的统计信息,或者您可能需要配置收集更细粒度的统计信息。

如果您显示表描述(包括索引)、查询的 EXPLAIN ANALYZE 输出以及硬件描述,人们将能够提供更具体的建议。

关于PostgreSQL 查询不使用索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10574417/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com