索引cond没有出现在postgres查询计划中

时间:2016-07-25 12:46:36

标签: postgresql indexing sql-execution-plan

我正在阅读article,并决定自己尝试一下。

在添加索引之前:

我有表BookHibernate,sql是由hibernate生成的:

CREATE TABLE bookhibernate
(
  book_id bigint NOT NULL,
  bought boolean,
  genre character varying(255),
  name character varying(255) NOT NULL,
  price integer NOT NULL,
  author_id bigint,
  CONSTRAINT bookhibernate_pkey PRIMARY KEY (book_id),
  CONSTRAINT fk_hlepqn9vy6biuo6vn47jo5ewx FOREIGN KEY (book_id)
      REFERENCES authorhibernate (author_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_r9o6704wcbcawmruyqojj4nab FOREIGN KEY (author_id)
      REFERENCES authorhibernate (author_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);

所以我致电explain analyze

explain analyze select * from bookhibernate where bookhibernate.price > 10

它给了我:

"Seq Scan on bookhibernate  (cost=0.00..1.02 rows=1 width=1053) (actual time=0.007..0.008 rows=2 loops=1)"
"  Filter: (price > 10)"
"Planning time: 0.054 ms"
"Execution time: 0.021 ms"

添加索引后

create index my_index on bookhibernate(price);

添加索引并执行相同的explain analyze后,我发现execution plan没有更改,我看到Filter: (price > 10)注册,但我希望看到Index cond: (price > 10)。< / p>

为什么我的期望会失败?

更新:

我被告知这是因为小桌子大小。这听起来很合理,而且这是真的。但我尝试了对1000行表的查询。

  1. 为什么Postgres决定使用过滤?为什么更好?
  2. Filter: (price > 10)的幕后背后是什么?这个算法的复杂性是什么?

1 个答案:

答案 0 :(得分:1)

表大小非常小,以至于PostgreSQL执行顺序扫描比使用索引更有效。如果您希望PostgreSQL完全考虑索引,请在表中添加更多行。

不仅表大小,而且条件的选择性都会影响优化器决定是否使用索引。 如果许多书籍的price大于10,则使用索引扫描效率较低,因为这涉及随机I / O(索引页面不会按顺序存储在磁盘上)。在这种情况下,顺序扫描总是更有效。

有几个PostgreSQL配置参数会影响PostgreSQL选择索引的可能性,最重要的是random_page_cost

您可以通过设置enable_seqscan = off然后再次运行EXPLAIN查询来测试您的索引是否符合条件。 使用此设置,如果可能的话,PostgreSQL将使用索引扫描。