空间影响
该空间的影响在这个职位由@Erwin Brandstetter修改谈起
简而言之,如果数据库包含以下内容,则您将保存一位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索引是否更快,而我无法证实这一点。您可以在邮件列表中找到Scott Marlowe所提供的非常有用的线程,该线程讨论了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时使用seq扫描。两个部分索引的大小相同。并且,完整索引(未显示)的大小相同。按照相同的方法,我用一个序列1..1e5
,,一个null / 0值和另一个序列加载了表1..1e5
。两种方法都能够找到带有覆盖整个表的索引的null / 0。
TLDR;摘要
我无法以一种或另一种方式来证实我认为值得考虑的大多数性能问题,因为这些问题包括计划者的不足。使用null保存ram的好处是真实的。通过不使用null节省的磁盘空间可以忽略不计,这对于具有一NULLABLE
列或少于8列的表来说是一个夸大的说法。在这些情况下,不会节省磁盘空间。