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

时间:2015-07-27 22:47:35

标签: postgresql

这是我的表(实际上是物化视图),在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)

我刚刚运行VACUUM ANALYZE vw_presentation_summary,因此查询规划器应该是最新的。

现在,如果我运行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)

解释链接:http://explain.depesz.com/s/nTL4

为什么运行Seq Scan而不是索引查找?

2 个答案:

答案 0 :(得分:2)

LIKE运算符不能用常规索引实现,除非使用" C"语言环境,因此您可以对所有行进行顺序扫描。您需要的是列上的varchar_pattern_ops index" presentation_code"。所以你应该有这样的索引:

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

你也可以考虑一个trigram index,虽然这里并不是绝对必要的。

答案 1 :(得分:-1)

数据库不使用索引只有两个原因:

  1. 它不能(索引不符合条件)
  2. 它不想(优化器估计完全扫描会更快)
  3. 更正:我最初认为这是#2的情况,但正如另一个答案所解释的那样,它实际上是#1。