mysql> EXPLAIN select * from t_user WHERE name = 'yangl'; +----+-------------+--------+------+---------------+----------+---------+-------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------+----------+---------+-------+------+--------------------------+ | 1 | SIMPLE | t_user | ref | idx_name | idx_name | 153 | const | 1 | Using where; Using index | +----+-------------+--------+------+---------------+----------+---------+-------+------+--------------------------+ 1 row in set (0.04 sec)
mysql>
关联表查询
1 2 3 4 5 6 7 8 9 10
mysql> EXPLAIN SELECT * FROM t_user_balance AS usba LEFT JOIN t_user AS tuser on tuser.id = usba.uid; +----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------+ | 1 | SIMPLE | usba | ALL | NULL | NULL | NULL | NULL | 4 | NULL | | 1 | SIMPLE | tuser | eq_ref | PRIMARY | PRIMARY | 4 | test_transaction.usba.uid | 1 | NULL | +----+-------------+-------+--------+---------------+---------+---------+---------------------------+------+-------+ 2 rows in set (0.04 sec)
mysql>
5、range
出现在 in(),between ,> ,<, >= 等操作符中。使用一个索引来查询给定范围的行。
range 比较好理解,它是索引上的范围查询,它会在索引上扫码特定范围内的值
in
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select * from t_user where id in (1,2); +----+------------+--------+-------+--------------+----------+---------+------+-------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+------------+--------+-------+--------------+----------+---------+------+-------+-----------------------+ | 1 | SIMPLE | t_user | index | PRIMARY | idx_name | 153 | NULL | 4 | Using where; Using index | +----+------------+--------+-------+--------------+----------+---------+------+-------+-----------------------+ 1 row in set (0.04 sec)
mysql>
between
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select * from t_user where id BETWEEN 1 and 3; +----+------------+--------+-------+--------------+----------+---------+------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+------------+--------+-------+--------------+----------+---------+------+-------+-------------+ | 1 | SIMPLE | t_user | range | PRIMARY | PRIMARY | 4 | NULL | 3 | Using where | +----+------------+--------+-------+--------------+----------+---------+------+-------+-------------+ 1 row in set (0.04 sec)
mysql>
<,>,<=,>=
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select * from t_user where id > 2; +----+------------+--------+-------+--------------+----------+---------+------+-------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+------------+--------+-------+--------------+----------+---------+------+-------+-----------------------+ | 1 | SIMPLE | t_user | index | PRIMARY | idx_name | 153 | NULL | 4 | Using where; Using index | +----+------------+--------+-------+--------------+----------+---------+------+-------+-----------------------+ 1 row in set (0.04 sec)
mysql>
6、index
扫描全表索引( index 是从索引中读取的,所有字段都有索引,而 all 是从硬盘中读取),比ALL要快。
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select * from t_user ; +----+-------------+--------+-------+---------------+----------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+-------+---------------+----------+---------+------+------+-------------+ | 1 | SIMPLE | t_user | index | NULL | idx_name | 153 | NULL | 4 | Using index | +----+-------------+--------+-------+---------------+----------+---------+------+------+-------------+ 1 row in set (0.04 sec)
mysql>
7、all
即全表扫描,需要从头到尾去查找所需要的行。一般这种情况下这需要增加索引来进行查询优化了
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select * from t_user_balance; +----+-------------+----------------+------+---------------+------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------------+------+---------------+------+---------+------+------+-------+ | 1 | SIMPLE | t_user_balance | ALL | NULL | NULL | NULL | NULL | 4 | NULL | +----+-------------+----------------+------+---------------+------+---------+------+------+-------+ 1 row in set (0.04 sec)
mysql>
总结
type类型从快到慢:system > const > eq_ref > ref > range > index > ALL
mysql> EXPLAIN select distinct id from t_user_balance; -- id 是索引列 +----+-------------+----------------+-------+-----------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------------+-------+-----------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | t_user_balance | index | PRIMARY,idx_uid | idx_uid | 4 | NULL | 4 | Using index | +----+-------------+----------------+-------+-----------------+---------+---------+------+------+-------------+ 1 row in set (0.04 sec)
mysql>
usingfilesort
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select balance from t_user_balance order by balance asc; +----+-------------+----------------+------+---------------+------+---------+------+------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------------+------+---------------+------+---------+------+------+----------------+ | 1 | SIMPLE | t_user_balance | ALL | NULL | NULL | NULL | NULL | 4 | Using filesort | +----+-------------+----------------+------+---------------+------+---------+------+------+----------------+ 1 row in set (0.04 sec)
mysql>
在使用 order by 的情况下出现,mysql 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。此时 mysql 会根据连接类型浏览所有符合条件的记录,并保存排序关键字和行指针,然后排序关键字并按顺序检索行信息。这种情况下要考虑使用索引来优化的。
1 2 3 4 5 6 7 8 9
mysql> EXPLAIN select id from t_user_balance order by id asc; -- id 是索引列 +----+-------------+----------------+-------+---------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------------+-------+---------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | t_user_balance | index | NULL | PRIMARY | 4 | NULL | 4 | Using index | +----+-------------+----------------+-------+---------------+---------+---------+------+------+-------------+ 1 row in set (0.04 sec)