【问题标题】:Does setting "NOT NULL" on a column in postgresql increase performance?在 postgresql 的列上设置“NOT NULL”会提高性能吗?
【发布时间】:2010-11-16 09:03:29
【问题描述】:

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

【问题讨论】:

    标签: performance postgresql database-design null


    【解决方案1】:

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

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

    只有在 中有任何 NULL 值时才分配空位图。对于行中的 每个 列,它是一个位(NULL 与否)。对于最多 8 列的表,空位图实际上是完全免费的,在元组标题和行数据之间使用一个备用字节。之后,空间以MAXALIGN 的倍数分配(通常为 8 个字节,覆盖 64 列)。填充丢失了差异。因此,您为每行中的第一个 NULL 值支付全价(低价!)。额外的 NULL 值只能节省空间。

    任何非空值的最小存储要求是 1 字节(boolean"char"、...)或通常更多,加上(可能)用于对齐的填充。阅读data types 或查看系统表pg_type 中的血腥细节。

    关于空存储的更多信息:

    【讨论】:

    • “检查几个周期”是什么意思?
    • @MattDiPasquale:Postgres 需要强制执行约束并在不满足时引发异常。由于对 NULL 的测试非常简单,因此成本可以忽略不计。
    【解决方案2】:

    如果可以避免,最好不要让列为 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 以降低遇到优化不佳查询的机会.

    【讨论】:

    • 很好的评论...我不知道 not null 和索引之间的关系。谢谢大佬!
    【解决方案3】:

    不,只要您实际上不在表中存储 NULL,索引看起来就完全相同(并且同样有效)。

    不过,将列设置为 NOT NULL 还有很多其他优点,所以当您不打算在其中存储 NULL 时,您应该始终将其设置为 :-)

    【讨论】:

      猜你喜欢
      • 2020-02-14
      • 1970-01-01
      • 2013-04-12
      • 2017-04-25
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多