经常看到有人问:"我该怎么为表做索引,才能使表联系更有效率 ",经常,有些人给出了答案,但是这些答案并没有基于为表联系做索引的基本理论.
该文的目的就是描述MYSQL表联结索引的基本理论,以一个很简单的示例开始,为大家展示MYSQL表联结的基本原理,然后再应用这些原理到更加复杂的4个表联结的请求。
我尽可能使用一些简单的测试数据,毕竟我们关心的是理论而不是表哪些表的哪些数据.因此我们就考虑这三个表:tblA,tblB,tblC. 每个表都有3列:col1,col2,col3(这样并不符合标准).现在列的类型,表的意义,以及计划要存储哪种数据,对我们来说没有关系.
SELECT * FROM tblA, tblB,tblC WHERE tblA.col1 = tblB.col1 AND tblA.col2 = tblC.col1;
And EXPLAIN for the query:
+-------+------+---------------+------+---------+------+------+-------------+ | table | type | possible_keys | key | key_len | ref | rows | Extra | +-------+------+---------------+------+---------+------+------+-------------+ | tblA | ALL | NULL | NULL | NULL | NULL | 1000 | | | tblB | ALL | NULL | NULL | NULL | NULL | 1000 | Using where | | tblC | ALL | NULL | NULL | NULL | NULL | 1000 | Using where | +-------+------+---------------+------+---------+------+------+-------------+
表实列出来使用这个命令,MYSQL当处理所有联结时,使用一次扫描,多次联结的方法.这就意味着mysql从第一个表读一行,然后在第二个表中找一匹配行然后再在第三个表中找,等等.当所有的表都找完后,MYSQL输出查询的列并通过表清单回溯直到在一个表中找到更多的匹配行.再从表中读取下行,再继续处理下个表.
正如MYSQL手册那个章节所说,当用explain命令去输出表时,MYSQL先读第一个表tblA,然后第二个表tblB,然后第三个表tblC,等等.来自前一个表的值被用于在当前表中找匹配的行.在我们的例子中,tblA中的值被用于找tblB中的行,然后来自tblB中的值被用于找tblC中的行.一旦一次全扫描完成(找到匹配行,在tblA,tblB,tblC),MYSQL并不返回tblA,它将返回tblB去看是否有更多的行和与当前来自tblA的值匹配.如果有,它得到这行,然后再到tblC中去匹配行.最重要的就是这是MYSQL连接的基本原理.