2017-04-26 11 views
0

対シーケンシャルスキャンを行うことを好む、なぜ私はそれが行の300万のように含まれている次の表は、主キーの選択:Postgresはインデックススキャン

create table log 
(
    id bigint default nextval('log_id_seq'::regclass) not null 
     constraint log_pkey 
      primary key, 
    level integer, 
    category varchar(255), 
    log_time timestamp, 
    prefix text, 
    message text 
); 

を持っています。

私は次のクエリを比較しています:

次計画得
EXPLAIN SELECT id 
     FROM log 
     WHERE log_time < now() - INTERVAL '3 month' 
     LIMIT 100000 

:ID命令でORDERで

Limit (cost=0.00..19498.87 rows=100000 width=8) 
    -> Seq Scan on log (cost=0.00..422740.48 rows=2168025 width=8) 
     Filter: (log_time < (now() - '3 mons'::interval)) 

と同じクエリを追加:

EXPLAIN SELECT id 
     FROM log 
     WHERE log_time < now() - INTERVAL '3 month' 
     ORDER BY id ASC 
     LIMIT 100000 

結果は

Limit (cost=0.43..25694.15 rows=100000 width=8) 
    -> Index Scan using log_pkey on log (cost=0.43..557048.28 rows=2168031 width=8) 
     Filter: (log_time < (now() - '3 mons'::interval)) 

私は、次の質問があります。

  • を指示BY ORDERの不在は、Postgresが行の順序を気にしないようにできます。彼らはソートされていてもよいでしょう。 ORDER BYのないインデックスを使用しない理由

    • Postgresは、このようなクエリで最初にインデックスを使用する方法はありますか? WHEREクエリの句にインデックスのない列が含まれていて、その列をフェッチする場合は、シーケンシャルデータベーススキャンが必要ですが、ORDER BYのクエリではそのことが示されません。
  • Postgresのマニュアルページは言う:テーブルの大部分をスキャンする必要があり、クエリのために

    それはI少ないディスクを必要とするため、明示的なソートは、インデックスを使用するよりも速くなる可能性があります/ Oによるシーケンシャルアクセスパターン

あなたは私のためにこの文を明確にしてくださいすることができ、次の?インデックスは常に注文されます。また、順序付けられた構造体を読み取ることは常に高速です。順序付けられていないデータを読み取り、それを手動で順序付けするよりも、常に(少なくともページスキャンの点で)順次アクセスになります。

答えて

4

この声明を明示していただけますか?インデックスは常に注文されます。また、順序付けられた構造体を読み取ることは常に高速です。順序付けられていないデータを読み取り、それを手動で順序付けするよりも、常に(少なくともページスキャンの点で)順次アクセスになります。

インデックスは順番に読み取られますが、postgresはテーブルから行を読み取ってフォローアップする必要があります。つまり、ほとんどの場合、インデックスが100行を識別する場合、ポストグルはテーブルに対して最大100のランダムな読み取りを実行する必要があります。

内部的には、postgresプランナは連続読み込みとランダム読み込みの重み付けが異なり、ランダム読み込みは一般にはるかに高価です。 seq_page_costrandom_page_costの設定でこれらが決まります。あなたが欲しいのならば、other settings you can view and tinker withがありますが、私は非常に慎重に変更することをお勧めします。

のは、以前の質問に戻りましょう:

命令BY ORDERの不在は、行の順序を気にしないのPostgresすることができます。彼らはソートされていてもよいでしょう。 ORDER BYのないインデックスを使用しない理由

理由は並べ替えです。後で説明するように、索引には制約列が含まれていないため、索引を使用する意味がありません。代わりに、プランナは基本的に "テーブル全体を読み、制約に適合する行を見つけ出し、それらの最初の100000を返します。"

ソートが変更されます。その場合、プランナは「このフィールドでソートする必要があり、すでにソートされているインデックスがあるため、インデックスからテーブルの行を読み込み、制約をチェックして100,000個が得られるまでそのセットを返す "。

コスト見積もり(たとえば '0.43..25694.15')は2番目のクエリの方がはるかに高いことに注意してください。プランナは、インデックススキャンから非常に多くのランダムな読み取りを行うと、並べ替えなしで一度にテーブル全体を読み込むだけです。

ご質問がありましたらお気軽にお問い合わせください。

関連する問題