简体   繁体   English

为什么Postgres不使用我的索引?

[英]Why isn't Postgres using my index?

Here is my table (actually a materialized view), in Postgres 9.4: 这是我在Postgres 9.4中的表格(实际上是一个物化视图):

  Materialized view "public.vw_presentation_summary"
      Column       |         Type          | Modifiers
-------------------+-----------------------+-----------
 processing_date   | date                  |
 presentation_code | character varying(15) |
 items             | numeric               |
 cost              | double precision      |
Indexes:
    "vw_idx_presentation_summary" btree (presentation_code)

I have just run VACUUM ANALYZE vw_presentation_summary , so the query planner should be up to date. 我刚刚运行VACUUM ANALYZE vw_presentation_summary ,所以查询计划程序应该是最新的。

Now if I run explain (analyse, buffers) select * from vw_presentation_summary where presentation_code LIKE '0205051I0BB%' this is what I see: 现在,如果我运行explain (analyse, buffers) select * from vw_presentation_summary where presentation_code LIKE '0205051I0BB%'这就是我看到的内容:

                                                         QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
 Seq Scan on vw_presentation_summary  (cost=0.00..23202.16 rows=182 width=32) (actual time=0.440..222.383 rows=224 loops=1)
   Filter: ((presentation_code)::text ~~ '0205051I0BB%'::text)
   Rows Removed by Filter: 1115229
   Buffers: shared hit=9259
 Planning time: 0.760 ms
 Execution time: 222.524 ms
(6 rows)

Explain link: http://explain.depesz.com/s/nTL4 说明链接: http : //explain.depesz.com/s/nTL4

Why is this running a Seq Scan not an index lookup? 为什么这运行Seq扫描而不是索引查找?

The LIKE operator can not be implemented with a regular index except when using the "C" locale, hence you get a sequential scan over all rows. 除非使用“ C”语言环境,否则无法使用常规索引来实现LIKE运算符,因此可以对所有行进行顺序扫描。 What you need is a varchar_pattern_ops index on your column "presentation_code". 您需要的是“ presentation_code”列上的varchar_pattern_ops索引 So you should have an index like so: 所以你应该有一个像这样的索引:

CREATE INDEX "vw_idx_presentation_summary_vcops"
  ON "vw_presentation_summary" (presentation_code varchar_pattern_ops);

You could also consider a trigram index , although that would not be strictly necessary here. 您也可以考虑使用trigram索引 ,尽管在这里并不一定要这么做。

There are only two reasons for a database not to use an index: 数据库不使用索引的原因只有两个:

  1. It can't (index is not eligible) 不能(索引不符合条件)
  2. It doesn't want to (optimizer estimates that full scan will be faster) 它不想(优化程序估计完整扫描会更快)

Correction: I initially thought that this was the case of #2, but as another answer has explained, it is in fact #1. 更正:我最初以为是#2,但正如另一个答案所解释的,它实际上是#1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM