在postgresql中对列设置“NOT NULL”是否会提高性能?

pkwftd7m  于 2022-12-23  发布在  PostgreSQL
关注(0)|答案(3)|浏览(401)

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

wgmfuz8q

wgmfuz8q1#

设置NOT NULL本身对性能没有影响。检查需要几个周期-无关紧要。
但是你可以通过实际使用NULL而不是哑值来提高性能。根据数据类型,你可以保存大量的磁盘空间和RAM,从而加速一切。
仅当 row 中有任何NULL值时,才会分配空位图。该行中的 * 每 * 列都有一位(NULL或NOT)。对于最多8列的表,空位图实际上是完全空闲的,在元组标头和行数据之间使用一个备用字节。之后,以MAXALIGN的倍数分配空间(通常为8个字节,覆盖64列)。差异会因填充而丢失。因此,您需要为每行中的第一个NULL值支付全价(低!)。额外的NULL值只能保存空间。
任何非空值的最小存储要求是1个字节(boolean"char",...)或通常 * 更多 *,加上(可能的)对齐填充。阅读data types或检查系统表pg_type中的血腥细节。
有关空存储的详细信息:

rhfm7lfc

rhfm7lfc2#

如果可以避免的话,保持列不为NULL总是一个很好的理想选择,因为使用的语义是如此混乱;请参阅What is the deal with NULLs?,以获得关于这些问题如何给您带来麻烦的讨论。
在PostgreSQL 8.2之前的版本中,软件不知道如何对最常见的类型索引进行比较(b树),其方式包括在其中找到NULL值。在documentation on index types的相关位中,您可以看到描述为“但请注意,ISNULL不等同于=,并且不可索引”。这样做的缺点是,如果您指定的查询要求包含NULL值,计划员可能无法使用这种情况下的明显索引来满足它。举个简单的例子,如果您有一个ORDER BY语句,可以使用索引来加速它的速度,但是您的查询也需要返回NULL值,优化器不能使用该索引,因为结果将丢失任何NULL数据--因此是不完整的和无用的。优化器知道这一点,并将改为对表进行无索引扫描,这可能是非常昂贵的。
PostgreSQL improved this in 8.3,“索引列上的IS NULL条件可以与B树索引一起使用”。因此,尝试索引具有NULL值的内容可能会使您焦头烂额的情况已经减少。但由于NULL语义仍然非常痛苦,您可能会遇到这样的情况,即使是8.3计划程序也无法完成您所期望的操作,因为它们,您仍然应该尽可能使用NOTNULL来降低遇到优化效果不佳的查询的可能性。

72qzrwbm

72qzrwbm3#

不,只要您实际上不在表中存储NULL,索引看起来就完全一样(而且同样有效)。
不过,将列设置为NOT NULL还有很多其他优点,所以当您不打算在其中存储NULL时,应该 * 始终 * 将其设置为NOT NULL:-)

相关问题