索引空值以在 DB2 上快速搜索

Posted

技术标签:

【中文标题】索引空值以在 DB2 上快速搜索【英文标题】:Indexing nulls for fast searching on 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,我希望数据库能够运行,并在搜索树的一个步骤中将它们全部忽略。这似乎没有发生。 【参考方案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 日期。

【讨论】:

以上是关于索引空值以在 DB2 上快速搜索的主要内容,如果未能解决你的问题,请参考以下文章

从 json 会话返回值以在会话外使用

建模音乐(音符)以在特定时间快速搜索音符的最佳方法

Elasticsearch:如何在 Elasticsearch 中搜索空值

Elasticsearch:如何在 Elasticsearch 中搜索空值

Elasticsearch:如何在 Elasticsearch 中搜索空值

从搜索查询中获取唯一值以填充搜索过滤器选项