我的理解是,null在DB2中是不可索引的,所以假设我们有一个巨大的表(Sales),其日期列(sold_on)通常是日期,但偶尔(10%的时间)为null。 / p>

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

我们可以通过在sold_on和total columns

上添加索引来快速进行以下查询
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

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

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

有帮助吗?

解决方案

我不是DB2专家,但如果10%的值为null,我认为单独该列上的索引不会对您的查询有所帮助。 10%是太多而无法使用索引 - 它只是进行表扫描。如果你说2-3%,我认为它实际上会使用你的索引。

考虑一下页面/块上有多少条记录 - 比如说20.使用索引的原因是为了避免获取你不需要的页面。给定页面包含0个空值的记录的概率为(90%)^ 20或12%。那些不是很好的赔率 - 无论如何你需要获取88%的页面,使用索引并不是很有帮助。

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

其他提示

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

所以:我声称DB2在非主键索引中没有NULL问题。

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

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top