3

はい、fillfactorまた。私は何時間も読んでいますが、それぞれのケースに何が最適かを判断することはできません. 断片化がいつ、どのように発生するのかわかりません。データベースを MS SQL Server から PostgreSQL 9.2 に移行しています。

ケース1

シーケンシャル (シリアル) PK で 10 ~ 50 回の挿入/分、20 ~ 50 回の読み取り/時間。

CREATE TABLE dev_transactions (
  transaction_id serial NOT NULL,
  transaction_type smallint NOT NULL,
  moment timestamp without time zone NOT NULL,
  gateway integer NOT NULL,
  device integer NOT NULL,
  controler smallint NOT NULL,
  token integer,
  et_mode character(1),
  status smallint NOT NULL,
  CONSTRAINT pk_dev_transactions PRIMARY KEY (transaction_id)
);

ケース 2

同様の構造であるシリアル PK のインデックスは、2 か月ごとに ~ 50.000 レジスタのブロック (ワンショット) に書き込み、読み取りは 10-50/分です。

50% の fillfactor は、各挿入が新しいページを生成し、既存の行の 50% を新しく生成されたページに移動することを意味しますか?

50% のフィルファクターは、新しいデータ ページの物理行間に空き領域が割り当てられることを意味しますか?

既存のページに空き領域が残っていない場合にのみ、新しいページが生成されますか?

ご覧のとおり、私は非常に混乱しています。PostgreSQL と index について読むための良いリンクかもしれませんfillfactor

4

1 に答える 1

13

FILLFACTOR

with onlyINSERTおよびどこでもofSELECTを使用する必要があります。sを使用して "小刻みに動く" つもりがない場合、メモリ ブロックごとに小刻みな余裕を残しても意味がありません。FILLFACTOR100UPDATE

背後にあるメカニズムFILLFACTORは単純です。INSERT■ 設定で宣言されたパーセンテージまで、データ ページ (通常は 8 kB ブロック) のみを埋めますFILLFACTOR。また、走っVACUUM FULLたりCLUSTERテーブルの上に乗ったりすると、ブロックごとに同じウィグル ルームが再確立されます。理想的には、これによりUPDATE新しい行バージョンを同じデータ ページに格納できるようになり、多数の を処理する場合にパフォーマンスが大幅に向上しますUPDATEHOT アップデートとの併用も効果的です。見る:

更新がない場合は、これのためにスペースを無駄にしないでくださいFILLFACTOR = 100(テーブルのデフォルトです)。

基本的な情報源:CREATE TABLEおよびのマニュアルCREATE INDEX

その他の最適化

しかし、あなたは何か他のことをすることができます-あなたは最適化の吸盤であるように見えるので... :)

CREATE TABLE dev_transactions(
  transaction_id serial PRIMARY KEY
, gateway integer NOT NULL
, moment timestamp NOT NULL
, transaction_type smallint NOT NULL
, status smallint NOT NULL
, device integer NOT NULL
, controler smallint NOT NULL
, token integer
, et_mode character(1)
);

これにより、データの配置に関してテーブルが最適化され、典型的な 64 ビット サーバーのパディングが回避され、数バイト、おそらく平均してわずか 8 バイトが節約されます。

NOT NULLごくわずかなパフォーマンス ボーナスのために、テーブルの先頭に列を保持します。

テーブルには9 つの列があります。これは、拡張NULL ビットマップ用に8 バイト余分にあることを意味します。これは、最初の 1 バイトの NULL ビットマップに8 列だけ収まります。 andを定義すると、すべての列がになり、NULL ビットマップが使用されなくなり、行ごとに 8 バイトが解放されます。列を宣言 しない場合でも、これは行ごとに機能します。すべての列に値がある場合、行の NULL ビットマップはありません。あなたの特別なケースでは、これはパラドックス効果につながり、値を入力すると、ストレージサイズが小さくなるか、少なくとも同じままになる可能性があります。
et_modetoken NOT NULLNOT NULL
NOT NULLet_modetoken

基本的な情報源: Database Physical Storageのマニュアル。

行のサイズ (値で満たされた) を元のテーブルと比較して、決定的な証拠を取得します。

SELECT pg_column_size(t) FROM dev_transactions t;

(さらに、次の行が 8 バイトの倍数で始まるため、行間のパディングが行われる可能性があります。)

于 2013-01-06T22:14:59.740 に答える