24

マニュアルのこのページによると、 indexes don't need to be maintained. ただし、継続率が の PostgresQL テーブルで実行しており、時間の経過 (数日) に伴い、クエリの大幅な低下が見られますupdates。インデックスを削除して再作成すると、クエリのパフォーマンスが回復します。deletesinserts

すぐに使用できる設定を使用しています。
このテストのテーブルは、現在、空の状態で開始され、50 万行にまで増加しています。かなり大きな行 (多数のテキスト フィールド) があります。

私たちはsearching based of an index, not the primary key(少なくとも通常の条件下では、インデックスが使用されていることを確認しました)

テーブルは、単一プロセスの永続ストアとして使用されています。Windows で Java クライアントを使用して PostgresQL を使用する。

insert and update performanceクエリのパフォーマンスを維持するためにあきらめても構わないと思っています。

アプリケーションに影響を与えることなく定期的にインデックスを削除および再構築できるように、データがさまざまな動的テーブルに分散されるように、アプリケーションを再構築することを検討しています。ただし、いつものように、これを機能させるには時間がかかります。構成または使用法に基本的なものが欠けているのではないかと思います。

と を検討forcing vacuumingrebuild to run at certain timesましたが、 と思われlocking period for such an action would cause our query to blockます。これはオプションかもしれませんが、リアルタイム (3 ~ 5 秒のウィンドウ) の影響があり、コードに他の変更を加える必要があります。

追加情報: 表と索引

CREATE TABLE icl_contacts
(
  id bigint NOT NULL,
  campaignfqname character varying(255) NOT NULL,
  currentstate character(16) NOT NULL,
  xmlscheduledtime character(23) NOT NULL,
...
25 or so other fields.  Most of them fixed or varying character fiel  
...
  CONSTRAINT icl_contacts_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE icl_contacts OWNER TO postgres;

CREATE INDEX icl_contacts_idx
  ON icl_contacts
  USING btree
  (xmlscheduledtime, currentstate, campaignfqname);

分析:

Limit  (cost=0.00..3792.10 rows=750 width=32) (actual time=48.922..59.601 rows=750 loops=1)
  ->  Index Scan using icl_contacts_idx on icl_contacts  (cost=0.00..934580.47 rows=184841 width=32) (actual time=48.909..55.961 rows=750 loops=1)
        Index Cond: ((xmlscheduledtime < '2010-05-20T13:00:00.000'::bpchar) AND (currentstate = 'SCHEDULED'::bpchar) AND ((campaignfqname)::text = '.main.ee45692a-6113-43cb-9257-7b6bf65f0c3e'::text))

と、はい、色々あるのは承知しておりますwe could do to normalize and improve the design of this table。これらのオプションの一部を利用できる場合があります。

この質問での私の焦点は、理解についてhow PostgresQL is managing the index and query over time (understand why, not just fix)です。やり直しや大幅なリファクタリングを行うと、多くの変更が発生します。

4

5 に答える 5

16

自動バキュームは、目的のパフォーマンスに合わせて構成されていれば、うまくいくはずです。

注: VACUUM FULL: これにより、テーブル統計が再構築され、ディスク領域の負荷が再利用されます。テーブル全体をロックします。

VACUUM: これにより、テーブル統計が再構築され、一部のディスク領域が再利用されます。本番システムと並行して実行できますが、パフォーマンスに影響を与える可能性のある大量の IO が生成されます。

ANALYZE: これにより、クエリ プランナーの統計が再構築されます。これは VACUUM によってトリガーされますが、単独で実行できます。

詳しい注意書きはこちら

于 2010-03-08T15:08:39.203 に答える
4

これは私にはインデックス肥大のようなにおいがします。このページをご案内します

http://www.postgresql.org/docs/8.3/static/routine-reindex.html

下部に次のように記載されています。

また、B ツリー インデックスの場合、新たに構築されたインデックスは、何度も更新されたインデックスよりもアクセスが多少速くなります。これは、論理的に隣接するページは、通常、新しく構築されたインデックスでも物理的に隣接するためです。(この考慮事項は現在、非 B ツリー インデックスには適用されません。) アクセス速度を改善するためだけに、定期的にインデックスを再作成する価値がある場合があります。

インデックスは「メンテナンスやチューニングを必要としない」と言って参照したページと矛盾しているようです。

「インデックスを同時に作成」を試しましたか?

于 2011-04-19T01:38:11.890 に答える
3

パフォーマンスに関しては、時刻とステータス情報を格納するために文字列を使用することはかなりのボトルネックです。まず第一に、テキストの索引は非常に非効率的です。同じ日に 2 回比較するには (使用した形式で) 少なくとも 11 回の比較が必要ですが、時間型を使用すると、単純に 1 回の比較に減らすことができます。これはインデックスのサイズにも影響し、大きなインデックスは検索が難しく、データベースはそれをメモリに保持しません。状態列にも同じ考慮事項が適用されます。州の小さなセットを表す場合は、州にマップされた整数を使用する必要があります。これにより、インデックスのノードが減少し、それに応じてインデックスのサイズが減少します。さらに、クエリで実際の時間を指定しないと、これらの組み込み型を使用しても、このインデックスは役に立ちません。

于 2011-04-17T06:08:54.110 に答える
2

xmlscheduledtime が比較される '2010-05-20T13:00:00.000' の値は、SQL の一部ですか、それともパラメーターとして提供されますか?

クエリの実行方法を計画するときに、フィールドが提供されたパラメーターよりも小さく、値がまだ不明である必要があると言っても、PostgreSQL は多くのことを続けることができません。それがほぼすべての行に一致するか、またはほとんどすべての行に一致するかはわかりません。

プランナーが統計をどのように使用するかについて読むと、データベースがそのプランを使用している理由を理解しようとするときに非常に役立ちます。

その複雑なインデックス内のフィールドの順序を変更するか、フィールド (campaignfqname、currentstate、xmlscheduledtime) を並べた新しいインデックスを作成すると、選択のパフォーマンスが向上する可能性があります。これにより、インデックスによってキャンペーンの fq 名と現在の状態が直接表示されるようになります。関心のあるものであり、xmlscheduledtime 範囲でのインデックス スキャンはすべて、目的の行になります。

于 2010-03-08T20:06:10.587 に答える
1

それは教科書の場合です。より積極的になるようにautovacuumを設定する必要があります。

于 2011-05-03T21:34:50.310 に答える