3

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のシーケンススキャン(コスト=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、しかしそれは私にとってはうまくいきません。ステートメントの効率は重要ではなく、単純さだけが重要です。

4

2 に答える 2

5

たぶん、その理由は、テーブルの行が少なすぎるためですか?

はい。テーブル内の合計20行の場合、seqスキャンは常にインデックススキャンよりも高速になります。いずれにせよ、これらの行は単一のデータベースブロックに配置される可能性があるため、seqスキャンに必要なのは1回のI/O操作のみです。

使用する場合

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

あなたは実際に何が起こっているかについてもう少し詳細を見ることができます。

ところで:textPostgresのデータ型(したがって予約語)でもあるため、列名として使用しないでください。

于 2013-03-18T11:09:36.217 に答える
1

あなたが見つけた例はDB2用で、pggenerate_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

上記のフィドルの 2 番目のクエリでは、インデックスのみのスキャンを使用する必要があります。

于 2013-03-18T11:01:38.110 に答える