在postgresql中的列上设置"NOT NULL"是否会提高性能?

rye*_*guy 10 postgresql performance null database-design

我知道这在MySQL中是个好主意.如果我没记错的话,在MySQL中它允许索引更有效地工作.

Erw*_*ter 17

设置NOT NULL本身对性能没有影响.检查的几个周期 - 无关紧要.

但您可以通过实际使用NULL而不是虚拟值来提高性能.根据数据类型,您可以节省大量磁盘空间和RAM,从而加速......一切.

如果在任何NULL值空位图只分配.它对于行中的每一列都是一位(NULL或不是).对于最多8列的表,使用元组头和行数据之间的备用字节,空位图实际上是完全空闲的.之后,空间被分配为MAXALIGN(通常为8个字节,覆盖64列)的倍数.填充的差异就会丢失.因此,您需要为每行中的第一个NULL值支付全部(低!)价格.额外的NULL值只能节省空间.

对于任何非空值的最小存储要求为1个字节(boolean,"char",...)或通常更多,再加上对准(可能)填充.阅读数据类型或检查系统表中的血腥细节pg_type.

有关空存储的更多信息

  • @MattDiPasquale:Postgres需要强制执行约束并在不满足时引发异常.由于对NULL的测试非常简单,因此成本可以忽略不计. (2认同)

Gre*_*ith 13

如果可以避免将列保持为NULL,这总是一个很好的理想,因为使用的语义非常混乱; 看看NULL的处理是什么?好好讨论一下如何让你陷入困境.

在高达8.2的PostgreSQL版本中,该软件不知道如何在最常见的类型索引(b-tree)上进行比较,其方式包括在其中查找NULL值.在索引类型的相关文档中,您可以看到描述为"但请注意,IS NULL不等于=且不可索引".这样做的有效缺点是,如果指定一个需要包含NULL值的查询,那么规划器可能无法使用该情况的明显索引来满足它.举个简单的例子,如果你有一个可以用索引加速的ORDER BY语句,但是你的查询也需要返回NULL值,那么优化器就不能使用那个索引,因为结果将丢失任何NULL数据 - 和因此是不完整和无用的.优化器知道这一点,而是将对表进行无索引扫描,这可能非常昂贵.

PostgreSQL 在8.3中改进了这一点,"索引列上的IS NULL条件可以与B树索引一起使用".因此,通过尝试使用NULL值索引某些内容可以使您被烧毁的情况已经减少.但是由于NULL语义仍然非常痛苦,并且你可能会遇到这样的情况,即使8.3计划程序因为它们而没有按照你的意愿行事,你仍然应该尽可能使用NOT NULL来降低遇到严重优化查询的机会.