The name index is an index over the last_name and first_name columns. The index can be used for lookups in queries that specify values in a known range for combinations of last_name and first_name values. It can also be used for queries that specify just a last_name value because that column is a leftmost prefix of the index (as described later in this section). Therefore, the name index is used for lookups in the following queries。
既然是最左原则,那么尝试着写一条SQL如下:
1 2 3 4 5 6 7 8
mysql> explain SELECT*FROM org WHERE org_name='1'and org_parent_id=1; +----+-------------+-------+------------+------+---------------+------------+---------+-------------+------+----------+-------------+ | id | select_type |table| partitions | type | possible_keys | key | key_len |ref|rows| filtered | Extra | +----+-------------+-------+------------+------+---------------+------------+---------+-------------+------+----------+-------------+ |1| SIMPLE | org |NULL|ref| index_name | index_name |773| const,const |1|100.00|Using index | +----+-------------+-------+------------+------+---------------+------------+---------+-------------+------+----------+-------------+ 1rowinset, 1 warning (0.01 sec)
可以看到其type是 ref 类型的,于是去mysql官网寻找ref类型的索引是什么:
All rows with matching index values are read from this table for each combination of rows from the previous tables. ref is used if the join uses only a leftmost prefix of the key or if the key is not a PRIMARY KEY or UNIQUE index (in other words, if the join cannot select a single row based on the key value). If the key that is used matches only a few rows, this is a good join type.
mysql> explain SELECT*FROM org_copy WHERE org_name='1'and org_parent_id>1; +----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+ | id | select_type |table| partitions | type | possible_keys | key | key_len |ref|rows| filtered | Extra | +----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+ |1| SIMPLE | org_copy |NULL|range| index_name | index_name |773|NULL|1|100.00|Using index condition| +----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+ 1rowinset, 1 warning (0.00 sec)
可以看到确实是使用了聚合索引,同时最后一列的 Using index condition也表明,这条查询语句会先通过索引来过滤出符合的数据,然后从过滤出来的数据里面在使用我们的where条件进行二次过滤,最终找出符合的数据。
解释
在Mysql里面,索引是以B+树的形式实现的,而索引又分为一级索引(主键)和二级索引(该文章中的index_name),其实在InnoDB里面,二级索引的叶子节点所存放的数据就是主键索引所对应的地址,这也称之为回表。 回到文章中来,在这篇文章中介绍的index_name索引里面,mysql是根据索引列的顺序,一个一个在索引里面进行查找过滤,如果该索引在某一列断开了,例如索引A的列是(A、B、C),但是在SQL里面却是where A ='a' and C='c',此时就会只使用该索引A的A列,这个跟B+树的特点有关。