【发布时间】:2010-09-23 04:33:19
【问题描述】:
我已经读过为索引选择的列应该在行之间很好地区分,即索引列不应该包含大量具有相同值的行。这表明布尔值或诸如性别之类的枚举对于索引来说是一个糟糕的选择。
但是假设我想按性别查找用户,在我的特定数据库中,只有 2% 的用户是女性,那么在这种情况下,当获取女性用户时,性别列似乎是一个有用的索引,但不是当得到所有男性用户时。
那么在这样的列上放置索引通常是个好主意吗?
【问题讨论】:
我已经读过为索引选择的列应该在行之间很好地区分,即索引列不应该包含大量具有相同值的行。这表明布尔值或诸如性别之类的枚举对于索引来说是一个糟糕的选择。
但是假设我想按性别查找用户,在我的特定数据库中,只有 2% 的用户是女性,那么在这种情况下,当获取女性用户时,性别列似乎是一个有用的索引,但不是当得到所有男性用户时。
那么在这样的列上放置索引通常是个好主意吗?
【问题讨论】:
索引低基数列以提高搜索性能在我的世界中很常见。 Oracle 支持为这些情况设计的“位图索引”。有关简短概述,请参阅 this article。
我的大部分经验是使用 Oracle,但我认为其他 RDBMS 支持类似的东西。
【讨论】:
不过,请不要忘记,您可能只有大约 2% 的时间会选择女性。其余时间,您将寻找男性。为此,直接表扫描(而不是索引扫描加上从表中访问数据)会更快。
有时,您还可以使用复合索引,将低基数列(枚举、布尔值)与高基数列(也许是出生日期)结合起来。这在很大程度上取决于完整的数据以及您将真正使用的查询。
我的经验是,关于男性/女性的索引很少真正有用。一般建议是有效的。还有一点要记住 - 添加或删除(或更新)行时必须维护索引。索引越多,每次修改操作要做的工作就越多,从而降低系统速度。
关于索引设计的整本书。
【讨论】:
在这种情况下,我会让服务器统计信息告诉我何时创建索引。除非您知道此查询将占主导地位,或者运行此类查询不会先验地满足您的性能目标,否则过早地创建索引可能只会降低您的性能而不是提高性能。此外,您可能需要考虑如何实际使用查询。在这种情况下,我的猜测是您通常会根据此列进行某种聚合,而不是简单地选择符合条件的用户。在那种情况下,无论如何你都会进行表扫描,而索引不会给你带来任何好处。
【讨论】: