【发布时间】:2010-11-16 09:03:29
【问题描述】:
我知道这在 MySQL 中是个好主意。如果我没记错的话,在 MySQL 中它可以让索引更有效地工作。
【问题讨论】:
标签: performance postgresql database-design null
我知道这在 MySQL 中是个好主意。如果我没记错的话,在 MySQL 中它可以让索引更有效地工作。
【问题讨论】:
标签: performance postgresql database-design null
设置NOT NULL 本身对性能没有影响。检查的几个周期 - 无关紧要。
但是您可以通过实际使用 NULL 而不是虚拟值来提高性能。根据数据类型,您可以节省大量磁盘空间和 RAM,从而加快 .. 一切。
只有在 行 中有任何 NULL 值时才分配空位图。对于行中的 每个 列,它是一个位(NULL 与否)。对于最多 8 列的表,空位图实际上是完全免费的,在元组标题和行数据之间使用一个备用字节。之后,空间以MAXALIGN 的倍数分配(通常为 8 个字节,覆盖 64 列)。填充丢失了差异。因此,您为每行中的第一个 NULL 值支付全价(低价!)。额外的 NULL 值只能节省空间。
任何非空值的最小存储要求是 1 字节(boolean、"char"、...)或通常更多,加上(可能)用于对齐的填充。阅读data types 或查看系统表pg_type 中的血腥细节。
关于空存储的更多信息:
【讨论】:
如果可以避免,最好不要让列为 NULL,因为使用的语义非常混乱;请参阅What is the deal with NULLs?,了解这些如何给您带来麻烦。
在最高 8.2 的 PostgreSQL 版本中,该软件不知道如何以包括在其中查找 NULL 值的方式对最常见的类型索引(b 树)进行比较。在documentation on index types 的相关位中,您可以看到描述为“但请注意 IS NULL 不等同于 = 并且不可索引”。这样做的有效缺点是,如果您指定一个需要包含 NULL 值的查询,则规划器可能无法使用针对这种情况的明显索引来满足它。举个简单的例子,如果你有一个可以用索引加速的 ORDER BY 语句,但是你的查询也需要返回 NULL 值,优化器就不能使用那个索引,因为结果会丢失任何 NULL 数据——并且因此是不完整和无用的。优化器知道这一点,而是改为对表进行无索引扫描,这可能非常昂贵。
PostgreSQL improved this in 8.3,“索引列上的 IS NULL 条件可以与 B 树索引一起使用”。因此,尝试用 NULL 值索引某些东西可能会被烧毁的情况已经减少。但是由于 NULL 语义仍然很痛苦,而且您可能会遇到这样的情况,即使 8.3 规划器也不会因为它们而执行您期望的操作,您仍应尽可能使用 NOT NULL 以降低遇到优化不佳查询的机会.
【讨论】:
不,只要您实际上不在表中存储 NULL,索引看起来就完全相同(并且同样有效)。
不过,将列设置为 NOT NULL 还有很多其他优点,所以当您不打算在其中存储 NULL 时,您应该始终将其设置为 :-)
【讨论】: