0

在 PostgreSQL 9 数据库中,有一个表包含一个串行字段 X,它是一个 PK(启用了 oid)和其他字段。

将 postgres 的 pgadmin 与该表一起使用 - 查询需要 30 秒。

如果我在同一个字段 X 上添加唯一索引 - pgadmin 中的相同查询需要 3 秒。

PK 是隐式索引: http ://www.postgresql.org/docs/current/static/indexes-unique.html

那么为什么显式索引会产生影响呢?

这是一个 pgadmin 问题吗?

我是否需要 PK 字段的显式索引?

4

2 回答 2

1

查看查询计划(EXPLAIN如果我没记错的话,您可以在 pgAdmin 中选择查询窗口中的选项),以更详细地了解正在发生的事情。您确定您不只是使用第二个查询从 postgresql 缓存中读取数据,或者无论触发查询的顺序如何,都始终如此行事?

此外,vacuum在删除/插入/操作大量数据后运行 a 会产生巨大的差异。如果添加(多余的)索引是原因,我会感到惊讶。正如@Eelke 指出的那样,您确定该列上已经定义了一个 PK 吗?

于 2012-10-17T10:31:54.103 回答
1

这里没有区别(pg 9.1.2),我认为这是一个工件(模式,大小写无关紧要?)

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE lutser
        ( id INTEGER NOT NULL PRIMARY KEY
        , val INTEGER NOT NULL
        );
INSERT INTO lutser(id,val)
SELECT g, g %31
FROM generate_series(1,100000) g
        ;

DELETE FROM lutser WHERE random() < .5;

VACUUM ANALYZE lutser;

EXPLAIN ANALYZE
SELECT COUNT(*) FROM lutser
WHERE id >= 1000 AND id < 2000
        ;

CREATE INDEX lutser_id ON lutser(id);

VACUUM ANALYZE lutser;

EXPLAIN ANALYZE
SELECT COUNT(*) FROM lutser
WHERE id >= 1000 AND id < 2000
        ;

结果:

NOTICE:  drop cascades to table tmp.lutser
DROP SCHEMA
CREATE SCHEMA
SET
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "lutser_pkey" for table "lutser"
CREATE TABLE
INSERT 0 100000
DELETE 50051
VACUUM
                                                          QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=20.28..20.29 rows=1 width=0) (actual time=0.294..0.295 rows=1 loops=1)
   ->  Index Scan using lutser_pkey on lutser  (cost=0.00..19.03 rows=499 width=0) (actual time=0.015..0.216 rows=487 loops=1)
         Index Cond: ((id >= 1000) AND (id < 2000))
 Total runtime: 0.343 ms
(4 rows)

CREATE INDEX
VACUUM
                                                         QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=19.03..19.04 rows=1 width=0) (actual time=0.232..0.232 rows=1 loops=1)
   ->  Index Scan using lutser_id on lutser  (cost=0.00..17.79 rows=497 width=0) (actual time=0.033..0.185 rows=487 loops=1)
         Index Cond: ((id >= 1000) AND (id < 2000))
 Total runtime: 0.266 ms
(4 rows)
于 2012-10-17T14:23:30.127 回答