【问题标题】:Indexing nulls for fast searching on DB2索引空值以在 DB2 上快速搜索
【发布时间】:2008-09-22 16:07:13
【问题描述】:

据我了解,空值在 DB2 中是不可索引的,因此假设我们有一个巨大的表 (Sales),其中的日期列 (sold_on) 通常是日期,但偶尔(10% 的时间)为空。

此外,让我们假设它是一个我们无法更改的遗留应用程序,因此这些空值会保留在那里并且意味着某些东西(比如说返回的销售额)。

我们可以通过在 sold_on 和 total 列上放置索引来快速进行以下查询

Select * from Sales 
where 
Sales.sold_on between date1 and date2
and Sales.total = 9.99

但是索引不会让这个查询变得更快:

Select * from Sales 
where 
Sales.sold_on is null
and Sales.total = 9.99

因为索引是在值上完成的。

我可以索引空值吗?也许通过更改索引类型?索引指标列?

【问题讨论】:

  • 理想情况下,如果空值是 0,我希望数据库能够运行,并在搜索树的一个步骤中将它们全部忽略。这似乎没有发生。

标签: sql performance indexing null db2


【解决方案1】:

您从哪里得到 DB2 不索引 NULL 的印象?我在支持该声明的文档或文章中找不到任何内容。我刚刚使用 IS NULL 限制在一个大表中执行了一个查询,该限制涉及一个包含一小部分 NULL 的索引列;在这种情况下,DB2 肯定使用了索引(通过 EXPLAIN 验证,并通过观察数据库立即响应而不是花时间执行表扫描)。

所以:我声称 DB2 对非主键索引中的 NULL 没有任何问题。

但正如其他人所写:您的数据可能以 DB2 认为使用索引不会更快的方式组合。或者数据库的统计信息对于所涉及的表不是最新的。

【讨论】:

    【解决方案2】:

    我不是 DB2 专家,但如果 10% 的值是空值,我认为仅该列上的索引不会帮助您的查询。 10% 太多了,无法使用索引——它只会进行表扫描。如果您说的是 2-3%,我认为它实际上会使用您的索引。

    想想一个页面/块上有多少条记录——比如 20 条。使用索引的原因是避免获取您不需要的页面。给定页面包含 0 个空记录的几率是 (90%)^20,即 12%。这些可能性不大——无论如何您都需要获取 88% 的页面,使用索引并不是很有帮助。

    但是,如果您的 select 子句仅包含几列(而不是 *) - 只包含 salesid,您可能会让它使用 (sold_on,salesid) 上的索引,因为读取数据页会' 不需要 -- 所有数据都在索引中。

    【讨论】:

    • 抱歉,我试图让问题尽可能简单(我们的实际查询是无数行)。
    【解决方案3】:

    经验法则是,索引最多可用于记录 15% 的值。 ...所以索引可能在这里有用。

    如果 DB2 不会索引空值,那么我建议添加一个布尔字段 IsSold,并在设置了 sold_on 日期时将其设置为 true(这可以在触发器中完成)。

    这不是最好的解决方案,但它可能是您需要的。

    【讨论】:

    • 是的,这是我们潜在的解决方案之一。但看起来我应该能够在某个地方拨动开关,而且我们还不需要触发器。
    【解决方案4】:

    Troels 是正确的;即使 SOLD_ON 值为 NULL 的行也会受益于该列上的索引。如果您在 SOLD_ON 上进行范围搜索,则可以通过创建以 SOLD_ON 开头的聚集索引来获得更多好处。在此特定示例中,维护基于 SOLD_ON 的集群顺序可能不需要太多额外开销,因为添加的较新行很可能具有较新的 SOLD_ON 日期。

    【讨论】:

      猜你喜欢
      • 2021-10-01
      • 2023-01-05
      • 2010-10-25
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      • 2018-10-10
      相关资源
      最近更新 更多