4

我的理解是空值在 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

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

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

4

4 回答 4

5

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

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

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

于 2009-01-01T21:45:46.450 回答
4

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

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

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

于 2008-09-22T16:15:50.413 回答
1

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

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

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

于 2008-09-22T17:04:33.680 回答
0

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

于 2009-06-17T01:53:33.270 回答