スペースの影響
スペースへの影響は@Erwin Brandstetterことで、この記事での話されています
簡単に言うと、データベースが持っている場合、1 totalColumns - 8
ビットを最も近いバイト(またはMAXALIGN
)に切り上げて保存します。
- 8列以上
- テーブルのすべての列は
NOT NULL
パフォーマンスへの影響
ただし、@ Erwin BrandstetterによるSEに関するこの投稿では、
- 「NOT NULLを設定してもパフォーマンス自体には影響しません。チェックのための数サイクル-無関係です。」
- 「...ダミー値の代わりにNULLを実際に使用する。データ型によっては、多くのディスク容量とRAMを節約できるので、すべてを高速化できます。」
@Renzoには、パフォーマンスへの影響についての回答があります。私は、PostgreSQLには該当しないと思います。PostgreSQLに関連していることを実証するものは何も見つかりません。保存されたサイクルが何であれ、最も基本的なクエリでさえ定量化することはできません。
CREATE TABLE foo (
a int,
b int NOT NULL,
x float,
y float NOT NULL
);
INSERT INTO foo ( a, b, x, y )
SELECT x, x, x, x
FROM generate_series(1,1E7) AS X(x);
EXPLAIN ANALYZE SELECT 1/a FROM foo;
EXPLAIN ANALYZE SELECT 1/b FROM foo;
EXPLAIN ANALYZE SELECT 1/x FROM foo;
EXPLAIN ANALYZE SELECT 1/y FROM foo;
さらに、いくつかのテストを実行して、NULLインデックスがこれまでより高速であるかどうかを確認しましたが、それを実証できませんでした。スコットマーロウのこのすばらしい便利なスレッドは、9.1のクエリプランナーが異なるWHERE句で部分インデックスを使用できることについて述べているメーリングリストで見つけることができます。以下を実行してこれをテストしました
CREATE TABLE foo ( a int );
CREATE TABLE bar ( a int NOT NULL );
INSERT INTO foo
SELECT null FROM generate_series(1,1e5) AS x
UNION ALL
SELECT 10
UNION ALL
SELECT null FROM generate_series(1,1e5) AS x
;
INSERT INTO bar
SELECT 0 FROM generate_series(1,1e5) AS x
UNION ALL
SELECT 10
UNION ALL
SELECT 0 FROM generate_series(1,1e5) AS x
;
今、私はインデックスを作成しました、
CREATE INDEX foobar ON foo(a) WHERE a IS NOT NULL;
CREATE INDEX barbar ON bar(a) WHERE a <> 0;
これらのどちらの場合でも、プランナーは選択時にインデックスを使用でき= 10
、NULLまたは0をそれぞれ検索するときにシーケンススキャンを使用できました。両方の部分インデックスは同じサイズでした。また、完全なインデックス(表示されていません)は同じサイズでした。同じ方法に従って、1つのシーケンス1..1e5
と1つのnull / 0値、および別のシーケンスのをテーブルにロードしました1..1e5
。どちらの方法でも、テーブル全体をカバーするインデックスを持つnull / 0を見つけることができました。
TLDR; 概要
私は、プランナーの不備を含めるためにテストする価値があると私が考えたほとんどのパフォーマンスの懸念について、何らかの方法で何かを実証することはできません。ramを保存するためにnullを使用する利点は本当です。nullを使用しないことで節約されるディスク容量はごくわずかNULLABLE
です。これは、1 列または8列未満のテーブルでは誇張です。そのような場合、節約されるディスク領域はありません。