2016-07-25 8 views
0

私はこれを読んでarticle、私自身で例を試してみることにしました。インデックス追加する前にインデックスはpostgresクエリプランに表示されませんでした

私が持っているテーブルBookHibernateは、SQLはhibernateによって生成された:それは私を与える

explain analyze select * from bookhibernate where bookhibernate.price > 10 

CREATE TABLE bookhibernate 
(
    book_id bigint NOT NULL, 
    bought boolean, 
    genre character varying(255), 
    name character varying(255) NOT NULL, 
    price integer NOT NULL, 
    author_id bigint, 
    CONSTRAINT bookhibernate_pkey PRIMARY KEY (book_id), 
    CONSTRAINT fk_hlepqn9vy6biuo6vn47jo5ewx FOREIGN KEY (book_id) 
     REFERENCES authorhibernate (author_id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT fk_r9o6704wcbcawmruyqojj4nab FOREIGN KEY (author_id) 
     REFERENCES authorhibernate (author_id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 
WITH (
    OIDS=FALSE 
); 

は、だから私は explain analyzeと呼ばれます
"Seq Scan on bookhibernate (cost=0.00..1.02 rows=1 width=1053) (actual time=0.007..0.008 rows=2 loops=1)" 
" Filter: (price > 10)" 
"Planning time: 0.054 ms" 
"Execution time: 0.021 ms" 

は、インデックス追加した後:インデックスを追加し、同じexplain analyzeを実行した後

create index my_index on bookhibernate(price); 

を私はexecution planが変更されていないと私はFilter: (price > 10)レジスタを参照していることがわかり、私はIndex cond: (price > 10)を見て期待していました。

私の期待はなぜ失敗するのですか?

更新日:

私はそれが小さいため、テーブルのサイズを言われました。それは妥当と思われ、それは本当です。しかし、私は1000行のテーブルに対して私のクエリを試みました。

  1. Postgresはなぜフィルタリングを使用するのですか?それはなぜ好ましいですか?
  2. Filter: (price > 10)の背景は何ですか?このアルゴリズムの複雑さは何ですか?
+0

テーブルにデータがありますか?あなたはテーブル上で 'analyze'を実行しましたか? – jmelesky

+0

@jmelesky、yes、2 rows/yes –

+0

2行の場合、データベースはインデックスを使用しません。 –

答えて

1

テーブルサイズが小さすぎるため、PostgreSQLがインデックスを使用するよりも順次スキャンを実行する方が効率的です。 PostgreSQLでインデックスをまったく考慮するには、テーブルに行を追加します。

表のサイズだけでなく、条件の選択性も、索引を使用するかどうかのオプティマイザの決定に影響します。 多くの書籍に10より大きいpriceがある場合、ランダムI/O(インデックスページはディスクに順番に格納されません)が含まれるため、インデックススキャンを使用することは効率的ではありません。その場合、シーケンシャルスキャンが常に効率的です。

PostgreSQLがインデックスを選択する可能性に影響するいくつかのPostgreSQL設定パラメータがあります。最も重要なのはrandom_page_costです。

​​を設定し、再度EXPLAINクエリを実行することで、インデックスが適格かどうかをテストできます。 この設定では、PostgreSQLは可能であればインデックススキャンを使用します。

+0

ありがとうございます。私は1000行に対してクエリを実行しようとしました。そして、 'Postgres'は、インデックスでバイナリ検索を使用することをフィルタリングする方がよいと判断しました。なぜそれが起こったのですか?インデックスアルゴリズムが 'lg(n)'の場合、 'Filter:(price> 10)'のアルゴリズムの複雑さは? –

+0

私は答えを改善しました。単一の索引項目を選択することは 'O(ln(n))'ですが、索引の関連部分を検索することはできません。 –

関連する問題