具有重复值的列的数据库索引

Database index on a column with duplicate values

如果有 table 包含员工的详细信息,包括性别列,其值可以是 M/F。现在在此列上创建索引是否有意义,是否会使搜索更快?从逻辑上讲,如果我们使用包含 Gender 作为列的 where 子句触发 select 语句,它应该将搜索时间减少一半。但我听说这种索引不会有帮助,并且在执行查询时实际上会被数据库优化器忽略。但我不明白为什么?有人可以解释一下吗?

在大多数情况下,只能使用一个索引来优化数据库查询。如果一个查询需要匹配多个索引列,查询规划器将不得不决定使用这些索引中的哪一个。每个索引都有一个基数,大致是table中不同值的数量。具有更高基数的索引会更有效,因为选择与索引匹配的行将导致扫描很少的行以匹配其他条件。

gender 列上的索引只会将 table 减半。任何其他索引都会更有效。

打个比方,想想 phone 本书。如果您只有一本 phone 一本书可以介绍整个国家/地区,那么要搜索您想要的特定人物将会非常庞大​​且困难。所以 phone 书籍通常只为一个城市或一个地区的几个城市制作,以使其尺寸合理。但是,如果您拥有 "Male phone book" 而不是地区性 phone 书籍,那么对于整个国家来说,它几乎与 phone 书籍一样无法使用。创建新 phone 本书的标准是它们应该比整个国家的一本书小得多。当您从一个巨大的尺寸开始时,减少 2 倍并不是很有用。

据推测,性别具有两种价值观。一般来说,gender 上的索引不会有帮助。事实上,这可能是有害的。

如果您选择性别,没有索引,查询优化器会对数据库页面进行完整 table 扫描以满足查询。在一个典型的页面上,一半的条目会匹配查询,因此您会在第一次点击时开始获得结果。

在查询执行的这个阶段,索引通常用于减少读取的页数。但是,如果每一页都有一条"M"和"F"的记录,那么每一页还是要读一遍。更糟糕的是,使用索引意味着您从一个随机页面读取,然后从另一个页面读取,而不是仅按顺序读取值。跳转页面需要一些额外的时间。如果页面不能全部放入内存,就会出现一种称为抖动的情况,这可能需要非常非常长的时间。

聚簇索引是一个例外,其中页面上的值实际上是按值排序的。在那种情况下,使用索引的查询会快大约 50%,因为只需要读取页面。这在 "archive" table 中特别有效,您有经常搜索的活动记录。此标志可能出现在 10%、1% 或 0.1% 的记录上,聚集索引可以显着提高速度。

table 到 运行 的大型查询很少有 returns 一半的记录。很有可能,性别与其他列相结合将是包含在索引中的一个很好的候选者。