面题:mysql 在执行 sql 的时候是如何选择使用哪一个索引的?

    面试中,当面试官问出这个问题时,你以为这是在考察mysql的什么内容?我当时脑子过了一下,我知道一条sql在执行的时候,会通过查询缓存,sql解析器,预处理器,sql优化器,生成执行计划,调用存储过程的api,数据,这样一个大概过程。mysql在选择索引是在sql优化器这一步,可是具体如何选择索引的,我并无读过源码,因此这个问题就GG了。mysql

      回家后,我还在想这题到底考察的什么,而且查了一些资料,搞清楚了选择是怎么一回事。在不考虑临时表和排序的状况下,优化器的目的是经过选择合适索引找到扫描数据行数最少的方案,即选择“选择性”较高的索引。选择性=基数/数据总数。索引基数是数据列所包含的不一样值的数量。扫描行多少涉及到索引“基数”,可是“基数”经过采样来统计,自己是估算出来的并且不是实时的,索引数据不够精准,致使最终选出的方案在优化器看来最优,但实际执行起来并非最优。 mysql 优化器最终选择哪一个索引,须要具体采样数据来决定的,咱们并不能看出来或者算出来。面试

       可是优化器若是由于不许确的采样基数,没法选择最优索引怎么办? 这道题引伸出的考察点如何干预mysql选择索引。如何让 mysql 能选择咱们为某个 sql 所设计的最优索引,而不会由于优化器选择其余索引致使性能问题。sql

       方法一,在sql中经过 force index 指定索引,等于直接告诉优化器不要用你那不靠谱的采样了,就用这个索引吧。缺点就是耦合性太强,若是你换一个更好的index那你要去改sql了,维护麻烦。 api

      方法二,analyze table,主动让让索引的基数从新计算一下。缺点,不够实时,不够灵活,你不看着点又会跑偏了。缓存

     方法三,找出总是被错误选择的索引,若是做用不是很大,简单粗暴,删除。整个世界就清爽了。 性能

相关文章
相关标签/搜索