mysql> explain select t1.c_primary_key, t1.c_unique_key, t2.c_primary_key from t2 left join t1 on t1.c_primary_key=t2.c_primary_key order by t2.c_primary_key;
+----+-------------+-------+--------+---------------+---------+---------+-------------------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-------------------------+---------+-------------+
| 1 | SIMPLE | t2 | index | NULL | PRIMARY | 4 | NULL | 1179542 | Using index |
| 1 | SIMPLE | t1 | eq_ref | PRIMARY | PRIMARY | 4 | dbTest.t2.c_primary_key | 1 | NULL |
+----+-------------+-------+--------+---------------+---------+---------+-------------------------+---------+-------------+
right join跟left join相反,left join看左边的表,而right join看右边的表!
实际上看explain输出的第一个表示谁!
Group By子句:
Group By可以使用index进行分组统计,这里索引(c_multi_key_part1,c_multi_key_part2)满足查询需求。
mysql> explain select max(c_multi_key_part2),c_multi_key_part1 from t1 group by c_multi_key_part1;
+----+-------------+-------+-------+-------------------+-------------------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-------------------+-------------------+---------+------+---------+-------------+
| 1 | SIMPLE | t1 | index | c_multi_key_part1 | c_multi_key_part1 | 130 | NULL | 1181681 | Using index |
+----+-------------+-------+-------+-------------------+-------------------+---------+------+---------+-------------+
Group By中对索引的使用有两种,松散索引扫描和紧凑索引扫描。松散索引扫描需要读取的键值数量和分组的组的数量一样多,也就是比实际存在的键值数目少很多。而紧凑型扫描将读取所有满足条件的索引值。如下,统计c_key不同值的个数,Extra中Using index for group-by表示使用松散扫描。
mysql> explain select count(distinct c_key) from t1;
+----+-------------+-------+-------+---------------+-------+---------+------+---------+-------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+---------+-------------------------------------+
| 1 | SIMPLE | t1 | range | c_key | c_key | 65 | NULL | 1181682 | Using index for group-by (scanning) |
+----+-------------+-------+-------+---------------+-------+---------+------+---------+-------------------------------------+
紧凑扫描的例子这里不再给出。
Group By在没有合适索引的情况下,会使用临时表存储结果,然后对临时表进行排序操作,才最终得到结果。
mysql> explain select c_str_value from t1 group by c_str_value;
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
| 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 1181681 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+---------+---------------------------------+
而事实上,若是只要分组而不需要排序的情况下,那么可以使用oder by null,告诉服务器不需要对进过进行排序,如下,这样就没有了Using filesort。
mysql> explain select c_str_value from t1 group by c_str_value order by null;
+----+-------------+-------+------+---------------+------+---------+------+---------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+---------+-----------------+
| 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 1181681 | Using temporary |
+----+-------------+-------+------+---------------+------+---------+------+---------+-----------------+