在PostgreSQL 9数据库中,有一个表包含一个串行字段X,它是一个PK(启用oid),以及其他字段。
将postgres的pgadmin与该表一起使用 - 查询需要30秒。
如果我在同一个字段X上添加一个唯一索引 - pgadmin中的同一查询需要3秒。
PK是隐式索引: http://www.postgresql.org/docs/current/static/indexes-unique.html
那么为什么显式索引有所作为呢?
这是一个pgadmin问题吗?
我是否需要PK字段的显式索引?
答案 0 :(得分:1)
查看查询计划(在pgAdmin中,您可以在查询窗口中选择EXPLAIN
选项,如果我没记错的话),以查看更详细的内容。你确定你不只是使用第二个查询从postgresql缓存中读取数据,或者一直表现如此,无论查询的触发顺序如何?
此外,在删除/插入/操作大量数据后运行vacuum
,因为这会产生巨大的差异。如果添加一个(多余的)索引是我的原因,我会感到惊讶。正如@Eelke指出的那样,你确定已经在该列上定义了PK吗?
答案 1 :(得分:1)
这里没有区别(第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)