为什么PostgreSQL的没有使用一张小桌子索引?(Why is PostgreSQL not u

2019-07-21 20:35发布

我有PostgreSQL的如下表:

CREATE TABLE index_test
(
    id int PRIMARY KEY NOT NULL,
    text varchar(2048) NOT NULL,
    last_modified timestamp NOT NULL,
    value int,
    item_type varchar(2046)
);
CREATE INDEX idx_index_type ON index_test ( item_type );
CREATE INDEX idx_index_value ON index_test ( value )

我做出以下选择:

explain select * from index_test r where r.item_type='B';
explain select r.value from index_test r where r.value=56;

执行计划的解释是这样的:

Seq Scan on index_test r  (cost=0.00..1.04 rows=1 width=1576)
    Filter: ((item_type)::text = 'B'::text)'

据我了解,这是一个全表扫描。 现在的问题是:为什么不使用我的索引?

可能的原因是,我在我的表中的行过少? 我只有20人。 能否请您给我提供一个SQL语句很容易填充我用随机的数据表,检查索引问题?

我发现这篇文章: http://it.toolbox.com/blogs/db2luw/how-to-easily-populate-a-table-with-random-data-7888 ,但它并没有为我工作。 该语句的效率并不重要,只有简单。

Answer 1:

是。 对于表中的一个总的20行的扫描SEQ总是会比索引扫描速度更快。 机会是,这些行位于一个数据库块,无论如何,所以以次扫描只需要一个单一的I / O操作。

如果您使用

explain (analyze true, verbose true, buffers true) select ....

你可以看到什么是真正发生了更多的细节。

顺便说一句:你不应该使用text作为列名,因为这也是Postgres的数据类型(并因此保留字)。



Answer 2:

你已经找到了例子是DB2,在PG可以使用generate_series做到这一点。 例如像这样:

INSERT INTO index_test(data,last_modified,value,item_type) 
SELECT
    md5(random()::text),now(),floor(random()*100),md5(random()::text) 
    FROM generate_series(1,1000);
SELECT max(value) from index_test;

http://sqlfiddle.com/#!12/52641/3

在上面捣鼓第二个查询应该使用索引扫描只。



文章来源: Why is PostgreSQL not using my indexes on a small table?