【问题标题】:Why isn't Postgres using my index?为什么 Postgres 不使用我的索引?
【发布时间】:2015-10-18 07:38:24
【问题描述】:

这是我在 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 而不是索引查找?

【问题讨论】:

标签: postgresql


【解决方案1】:

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

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

您也可以考虑使用trigram index,尽管此处并非绝对必要。

【讨论】:

  • 谢谢!出于某种原因,我认为我的数据库使用的是 C 语言环境,但检查它不是。
【解决方案2】:

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

  1. 不能(索引不符合条件)
  2. 它不想(优化器估计全扫描会更快)

更正:我最初认为这是#2的情况,但正如另一个答案所解释的那样,它实际上是#1。

【讨论】:

  • 表中有大约 111 万行,您的建议是不可能的。
  • 哎呀,我的错。我在看“rows=182”,但这是输出大小估计。我错过了“过滤器删除的行:1115229”部分。
猜你喜欢
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2020-05-27
相关资源
最近更新 更多