0

PostgreSQL 9 データベースには、PK (oid 対応) であるシリアル フィールド X とその他のフィールドを含むテーブルがあります。

そのテーブルで 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 ではクエリ ウィンドウでオプションを選択できます)、何が起こっているのかをより詳細に確認してください。2 番目のクエリで postgresql キャッシュからデータを読み取っているだけでなく、クエリが実行される順序に関係なく、一貫してそのように動作していると確信していますか?

また、vacuum大量のデータを削除/挿入/操作した後に実行すると、大きな違いが生じる可能性があります。(余分な)インデックスを追加することが原因である場合、私は驚くでしょう。@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 に答える