我知道这在MySQL中是个好主意。如果我没记错的话,在MySQL中它允许索引更有效地工作。
答案 0 :(得分:17)
设置NOT NULL
本身对性能没有影响。检查的几个周期 - 无关紧要。
但是你可以通过实际使用NULL而不是虚拟值来提高性能。根据数据类型,您可以节省大量磁盘空间和RAM ,从而加快......一切。
只有在行中有任何NULL值时才会分配空位图。这是行中每个列的一位(NULL或不是)。对于最多8列的表,使用元组头和行数据之间的备用字节,空位图实际上是完全空闲的。之后,空间以MAXALIGN
的倍数分配(通常为8个字节,覆盖64列)。填充的差异就会丢失。因此,您为每行中的第一个NULL值支付全部(低!)价格。额外的NULL值只能节省空间。
任何非空值的最小存储要求是1个字节(boolean
,"char"
,...)或通常多更多,加上(可能)填充对齐。阅读data types或查看系统表pg_type
中的血腥详细信息。
有关空存储的更多信息:
答案 1 :(得分:12)
如果可以避免列,那么保持列为NULL总是一个很好的理想,因为使用的语义非常混乱;请参阅What is the deal with NULLs?,了解这些问题如何让您陷入麻烦。
在高达8.2的PostgreSQL版本中,该软件不知道如何在最常见的类型索引(b-tree)上进行比较,其方式包括在其中查找NULL值。在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来降低遇到严重优化查询的机会
答案 2 :(得分:2)
不,只要你没有在表中实际存储NULL,索引就会看起来完全一样(同样有效)。
将列设置为NOT NULL有很多其他优点,因此当您不打算在其中存储NULL时,总是将其设置为: - )