PostgreSQL查询不使用索引

Dav*_*ita 3 postgresql indexing

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

PersonId, Amount, Commission
Run Code Online (Sandbox Code Playgroud)

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

explain select * from "Order" where "PersonId" = 2 AND "Commission" > 3
Run Code Online (Sandbox Code Playgroud)

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

explain select * from "Order" where "PersonId" > 2 AND "Commission" > 3
Run Code Online (Sandbox Code Playgroud)

即使索引存在,它也会执行顺序扫描.甚至这个查询

explain select * from "Order" where "Commission" > 3 
Run Code Online (Sandbox Code Playgroud)

做顺序扫描.有人在乎解释原因吗?:-)

非常感谢你.

UPDATE

该表包含1亿行.我创建它只是为了测试PostgreSQL对MS SQL的性能.该表已经是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
Run Code Online (Sandbox Code Playgroud)

kgr*_*ttn 8

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

请注意,使用您描述的索引,需要扫描整个索引的所有行"PersonId" > 2; 除非你有很多负面值,否则"PersonId"很可能是大部分表格.

另请注意,如果您有一个小表 - 比如几千行或更少,通过索引访问行很少比扫描那几行快.计划对数据量敏感,而您使用少量行获得的计划不太可能与您使用大量行获得的计划相同.

事实上,如果没有选择最快的计划,您需要调整成本因素以更好地模拟机器成本.另一种可能性是您需要在autovacuum设置中更积极,以确保可以获得最新的统计信息,或者您可能需要配置更精细的统计信息的集合.

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