Mysql 对固定值很少但值占总行数不到25%的列进行索引

Mysql 对固定值很少但值占总行数不到25%的列进行索引,mysql,select,indexing,Mysql,Select,Indexing,我在一个表中有一个字段table\u name,它只能有20个不同的值。表中的总记录约为数万行。如果我执行这样的查询: SELECT * FROM table WHERE table_name = 'adasd'; 返回的记录最多占总行数的25%。大多数情况下,我只得到总记录的10%。这里是否有索引字段表\u name的范围?我听说要使索引正常工作,需要该字段中的值是唯一的或接近它。就我而言,这根本不是独一无二的。但我还听说,如果返回的行数比总行数少,那么就有理由建立索引 我该怎么做 不,它

我在一个表中有一个字段
table\u name
,它只能有20个不同的值。表中的总记录约为数万行。如果我执行这样的查询:

SELECT * FROM table WHERE table_name = 'adasd'; 
返回的记录最多占总行数的25%。大多数情况下,我只得到总记录的10%。这里是否有索引字段
表\u name
的范围?我听说要使索引正常工作,需要该字段中的值是唯一的或接近它。就我而言,这根本不是独一无二的。但我还听说,如果返回的行数比总行数少,那么就有理由建立索引


我该怎么做

不,它们不必是唯一的,就可以从使用索引中获得好处,但是,需要花一些时间来考虑DBMS在处理查询时做了什么:

全表扫描-顺序读取数据(即很少的寻道操作)

索引查找—对索引进行几次搜索以查找选定数据的开头,然后进行顺序读取(几次搜索)以标识基础表中的行,然后进行一次又一次的搜索以从表中提取行

价格昂贵

(完整表扫描的另一个影响是,它们更容易将热数据从缓存中刷新出来,但您应该首先解决主要问题)

在这种情况下,如果索引存在,DBMS不太可能使用它,即使索引存在,也可能比全表扫描慢。作为一个(非常)粗略的经验法则,只有当谓词识别的行数少于大约5%时,您才能从索引中获益(但它会根据索引和数据的相对大小而有所不同)

i、 不要在这个字段上添加索引


我认为您可能会从花一些时间思考为什么需要运行返回这么多行的查询中获益?

不,它们不必是唯一的,就可以从使用索引中获益,但是,请花一些时间考虑DBMS在处理查询时做了什么:

全表扫描-顺序读取数据(即很少的寻道操作)

索引查找—对索引进行几次搜索以查找选定数据的开头,然后进行顺序读取(几次搜索)以标识基础表中的行,然后进行一次又一次的搜索以从表中提取行

价格昂贵

(完整表扫描的另一个影响是,它们更容易将热数据从缓存中刷新出来,但您应该首先解决主要问题)

在这种情况下,如果索引存在,DBMS不太可能使用它,即使索引存在,也可能比全表扫描慢。作为一个(非常)粗略的经验法则,只有当谓词识别的行数少于大约5%时,您才能从索引中获益(但它会根据索引和数据的相对大小而有所不同)

i、 不要在这个字段上添加索引

我认为,花一些时间思考为什么需要运行返回这么多行的查询可能会让您受益匪浅。

修改后的答案 我刚刚了解到,创建索引并不意味着MySQL将使用它。记住这一点,我将重新表述我的答案:

如果(常规或您自己的)实践建议您这样做,您应该在该列上创建索引。MySQL将使用启发式;其中包括查看可用索引及其各自的基数,以确定使用或根本不使用索引的最佳索引

有关此主题的有趣阅读。

修改后的答案 我刚刚了解到,创建索引并不意味着MySQL将使用它。记住这一点,我将重新表述我的答案:

如果(常规或您自己的)实践建议您这样做,您应该在该列上创建索引。MySQL将使用启发式;其中包括查看可用索引及其各自的基数,以确定使用或根本不使用索引的最佳索引


关于此主题的有趣阅读。

是的,您可以为其编制索引column@SashiKant谢谢你能发布一个更详细的答案吗?这将有助于ppl未来的发展。@N.B.非常好。这澄清了我对索引的错误理解。你能把它贴出来作为答案吗?是的,你可以索引它column@SashiKant谢谢你能发布一个更详细的答案吗?这将有助于ppl未来的发展。@N.B.非常好。这澄清了我对索引的错误理解。我有这个疑问,这个博客和许多类似的文章都说,这取决于where子句可以产生多少行。但是有人说查询返回的记录根本不重要,只有基数才重要。我的问题是,索引依赖于返回的行还是仅仅依赖于基数(=该字段有多少不同的唯一值)?索引根据基数产生性能。越接近1越好。就这样。10个可能的值,db=基数中的10行可以是1。添加30k行,基数现在是10/30k。它与“返回的行”无关。@N.B.你是这么说的,但不是所有的链接。看到这个链接或者你提到的文章中提到的这个,索引会减慢你的查询速度;取决于值的分布。我建议你自己做个实验,看看这个指数是否有用。萨尔曼,正如问题中所说,现在的速度差不多,没有赢家。那是因为我只有那么多行。我试图得到它背后的理论。我有一个疑问,这篇博客和许多类似的文章说,这取决于where子句可以产生多少行。但是有人说查询返回的记录根本不重要,只有基数才重要。我的问题是,索引依赖于返回的行还是仅仅依赖于基数