发现MySQL的explain还是很有迷惑性的。
看下面两个sql的explain,(i,j)是tt的主键
mysql> explain select * from tt where i between 3 and 5 and j = 4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tt
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: NULL
rows: 8
Extra: Using where; Using index
1 row in set (0.00 sec)
mysql> explain select * from tt where i > 2 and i < 6 and j = 4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tt
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 8
Extra: Using where; Using index
1 row in set (0.00 sec)
看上去如果使用了between,那么MySQL可以用的索引的两列。但仔细的研究了一下,发现实际并不是这样。between 3 and 5可以写为(i>3 or i=3) and (i<5 or i=5),是这两个等号使用了两列,而大于和小于的判断仍然是index扫描,只用了一列。
再看另一个
mysql> explain select * from tt where i in (3,4,5) and j=4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tt
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: NULL
rows: 3
Extra: Using where; Using index
1 row in set (0.00 sec)
这个才是真正用了两列,可以看到这里估计的行数是3,而刚才两个是8。用 show status 可以看得更清楚一些:
mysql> show status like 'handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
6 rows in set (0.00 sec)
mysql> select * from tt where i in (3,4,5) and j=4;
+---+---+
| i | j |
+---+---+
| 3 | 4 |
+---+---+
1 row in set (0.00 sec)
mysql> show status like 'handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 4 |
| Handler_read_next | 1 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
6 rows in set (0.00 sec)
mysql> select * from tt where i between 3 and 5 and j = 4;
+---+---+
| i | j |
+---+---+
| 3 | 4 |
+---+---+
1 row in set (0.00 sec)
mysql> show status like 'handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 6 |
| Handler_read_next | 10 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
6 rows in set (0.00 sec)
后一个sql中有9次read_next_key,说明做了索引扫描。
分享到:
相关推荐
SQL语句性能分析之explain
mysqlexplain
详细讲解在Oracle中如何使用explain_plan,值得参考和收藏学习。
Mysql Explain
MySQL explain 笔记整理 MySQL explain 笔记整理
django-explain- 一个助手用于django queryset取得 EXPLAIN 或 EXPLAIN ANALYZE OUTPUT
mysql explain
在分析查询性能时,考虑EXPLAIN关键字同样很管用。EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作、以及MySQL成功返回结果集需要执行的行数。explain 可以帮助我们分析 select 语句,让...
Explain关键字详解,mysql分析工具,方便快速理解原理
NULL 博文链接:https://babydeed.iteye.com/blog/1567772
DB29.7Visual Explain教程帮助你在db29.7下把SQL或Xquery说明语句的访问方案作为一个图来查看。
Mysql Explain 详解
good material in learning db2 explain plan
Mysql Explain详细解析
oracle执行计划,oracle explain plan,在ORACLE数据库中,需要对SQL语句进行优化的话需要知道其执行计划,从而针对性的进行调整.ORACLE的执行计划的获得有几种方法,下面就来总结下
Mysql Explain 使用
Hive on Spark EXPLAIN statement : 讲述了 Common Join / Map join / Bucket Map Join / Sorted Merge Bucket Map Join / skew join 在explain 中的 树结构 。In Hive, command EXPLAIN can be used to show the ...
02-VIP-Explain详解与索引最佳实践.pdf
看懂MySQL的SQL EXPLAIN
Oracle中EXPLAIN PLAN的使用技巧