【问题标题】:Why is PostgreSQL not using my indexes on a small table?为什么 PostgreSQL 不在小表上使用我的索引?
【发布时间】:2013-03-06 16:05:49
【问题描述】:

我在 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;

执行计划的解释如下:

index_test r 上的 Seq 扫描(成本=0.00..1.04 行=1 宽度=1576) 过滤器:((item_type)::text = 'B'::text)'

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

可能是,原因是我的表中的行数太少?我只有20个。能否请您提供一条 SQL 语句,以便用随机数据轻松填充我的表以检查索引问题?

我找到了这篇文章:http://it.toolbox.com/blogs/db2luw/how-to-easily-populate-a-table-with-random-data-7888,但它对我不起作用。语句的效率不重要,重要的是简单。

【问题讨论】:

  • 如果效率不重要,只要简单,你为什么关心它是否使用索引?索引是不影响语义的性能优化——嗯,除了实现细节,如 Pg 的 UNIQUE 索引作为 UNIQUE 约束的实现。
  • 克雷格,“效率无关紧要”仅与插入虚拟行的方式有关,请原谅误导性短语。

标签: sql postgresql postgresql-performance


【解决方案1】:

可能是我的表行太少了?

是的。对于表中总共 20 行,seq 扫描总是比索引扫描快。很可能这些行无论如何都位于单个数据库块中,因此 seq 扫描只需要单个 I/O 操作。

如果你使用

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

您可以看到更多关于实际情况的详细信息。

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

【讨论】:

  • @KutaBeach 请注意,您可以强制进行索引扫描,以便通过使用enable_ 中记录的参数来测试是否可能为特定查询使用索引手册。这些参数仅用于测试目的,一般不应在生产中使用。
【解决方案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

上面小提琴中的第二个查询应该使用仅索引扫描。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 2022-01-15
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多