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

时间:2015-01-31 20:15:21

标签: mysql sql database indexing sybase

如果有一个包含员工详细信息的表格,其中包括一列Gender,其值可以是M / F.现在,在此列上创建索引是否有意义,是否会使搜索更快?逻辑上,如果我们使用where子句包含Gender作为列来激活select语句,它应该将搜索时间缩短一半。但我听说这种索引无济于事,并且在执行查询时实际上会被Database Optimizer忽略。但我不明白为什么?有人可以解释一下吗?

2 个答案:

答案 0 :(得分:10)

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

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

作为类比,想想电话簿。如果您有一个针对整个国家/地区的电话簿,那么搜索您想要的特定人员将会非常困难。因此,电话簿通常仅针对某个城市或某个地区的少数城市制作,以使其尺寸合理。但是,如果你有一个"男性电话簿"而不是区域电话簿,它将几乎像整个国家的电话簿一样无法使用。创建新电话簿的标准是它们应该比整个国家的书小得多。当您从一个巨大的尺寸开始时,减少2倍并不是非常有用。

答案 1 :(得分:7)

据推测,性别具有两个价值观。通常,gender上的索引不会有帮助。事实上,这可能是有害的。

如果选择性别而没有索引,查询优化器会对数据库页面执行全表扫描以满足查询要求。在典型页面上,一半条目将与查询匹配,因此您将在第一次点击时开始获得结果。

在查询执行的这个阶段,索引通常用于减少正在读取的页数。但是,如果每个页面都有“M”和“F”的记录,则仍然必须读取每个页面。更糟糕的是,使用索引意味着您从一个随机页面读取,然后从另一个页面读取,另一个,而不是仅按顺序读取值。跳转页面需要一些额外的时间。如果这些页面都不适合内存,那么就会出现一种叫做颠簸的情况,这可能需要非常长的时间。

对此的一个例外是聚簇索引,其中页面上的值实际上按值排序。在这种情况下,使用索引的查询将快50%,因为只需要读取页面。这在“归档”表中尤其有效,在该表中,您有经常搜索的活动记录。此标志可能出现在记录的10%,1%或0.1%上,并且聚集索引可以显着提高速度。

在大型表上运行返回一半记录的查询是很少见的。很可能,性别与其他专栏相结合将是包含在索引中的良好候选者。