索引空值以在 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 上快速搜索的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:如何在 Elasticsearch 中搜索空值
Elasticsearch:如何在 Elasticsearch 中搜索空值