一、背景
有个朋友问一个问题“能不能帮忙看下const和ref_eq有啥区别,mysql高性能书籍里面的讲得不太明白”。
结合这个具体问题,讲解一下这类问题我们该如何解决。
二、过程
2.1 源码大法
由于mysql源码貌似不是java写的,找起来也费劲,源码大法貌似先不能用,我们先放弃。
2.2 搜索引擎大法
搜到了一篇类似的博客
http://www.bubuko.com/infodetail-3091337.html
eq_ref: 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见主键或者唯一索引扫描 const: 表示通过索引一次就找到了,const用于比较primary_key和union,由于只匹配一条数据,所以很快,
找了很多这类博客,貌似讲得也不太清楚
或者StackOverFlow上查询,不过没发现好的解释。
2.3 翻书大法
找相关的比较经典的权威的图书。
比如我们找《MySQL深度剖析》,没有找到特别通俗的解释,放弃。
2.4 命令help大法
找了半天没找到类似 mysql explain --help这种命令,放弃。
如果有帮助命令,一般解释非常权威和详细。
2.5 官方文档大法
其实很多文章都是根据官方的文档自己翻译过来的,或者根据官方文档写的书,或者根据别人的理解写的文章。
因此看源码和看官方文档更权威。
我们找到了对应的文档:
https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#jointype_const
const 该表最多有一个匹配行, 在查询开始时读取。由于只有一行, 因此该行中列的值可以被优化器的其余部分视为常量。const 表非常快, 因为它们只读一次。
const用于将 "主键" 或 "唯一" 索引的所有部分与常量值进行比较。
这里的表述都是“an table”,而且示例也是单表,因此应该只在单表查询时。
https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#jointype_eq_ref
读取本表中和关联表表中的每行组合成的一行。除 了 system 和 const 类型之外, 这是最好的联接类型。当连接使用索引的所有部分时, 索引是主键或唯一非 NULL 索引时, 将使用该值。
eq_ref 可用于使用 =
运算符比较的索引列。比较值可以是常量或使用此表之前读取的表中的列的表达式。通常用在多表查询中。
这里总是提到"tables",且示例都是多个表,用在多表查询时。
三、learn more
另外跟据我们的learn more的习惯,我们可以去mysql官方文档中找到其他类型的详细说明和示例,系统掌握相关知识点。
这样我们遇到一个点不会的,我们就把整条线都掌握了。
我们还可以了解他们之间的好坏排序
type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:system > const > eq_ref> ref> fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index>all,一般来说,得保证查询至少达到range级别,最好能达到ref。
甚至可以看官方文档的其他章节内容。
四、demo大法
根据官方文档的解释,创建一个表去验证。动动手,印象更深刻。
此处略掉。
五、通法
这类问题,可以参考第二部分的几个步骤来解决。
源码,搜索引擎,翻书,命令帮助,官方文档,写demo验证等几个角度去找到想要的答案。