我正在阅读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行表的查询。
Postgres
决定使用过滤?为什么更好? Filter: (price > 10)
的幕后背后是什么?这个算法的复杂性是什么?答案 0 :(得分:1)
表大小非常小,以至于PostgreSQL执行顺序扫描比使用索引更有效。如果您希望PostgreSQL完全考虑索引,请在表中添加更多行。
不仅表大小,而且条件的选择性都会影响优化器决定是否使用索引。
如果许多书籍的price
大于10,则使用索引扫描效率较低,因为这涉及随机I / O(索引页面不会按顺序存储在磁盘上)。在这种情况下,顺序扫描总是更有效。
有几个PostgreSQL配置参数会影响PostgreSQL选择索引的可能性,最重要的是random_page_cost
。
您可以通过设置enable_seqscan = off
然后再次运行EXPLAIN
查询来测试您的索引是否符合条件。
使用此设置,如果可能的话,PostgreSQL将使用索引扫描。