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

时间:2020-03-06 14:32:53  来源:igfitidea点击:

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

此外,我们假设它是一个无法更改的旧版应用程序,因此这些null停留在那里并表示某些含义(例如,返回的销售收入)。

我们可以通过在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

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

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

解决方案

我不是DB2专家,但是如果值的10%为空,那么我认为仅该列上的索引不会对查询有所帮助。 10%太多了,以至于无法使用索引-它只会进行表扫描。如果我们谈论的是2-3%,我认为它实际上会使用指数。

考虑一个页面/块上有多少条记录,例如20。使用索引的原因是避免获取不需要的页面。给定页面将包含0个为空的记录的几率是(90%)^ 20,或者12%。这些并不是很好的选择-无论如何,我们都将需要获取88%的页面,使用索引不是很有帮助。

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

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

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

那不是最好的解决方案,但这可能是我们所需要的。

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

因此:我声称DB2在非主键索引中使用NULL没问题。

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

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