(1)Using where:
Using where其实一般见于直接针对一个表扫描,没用到索引,然后where里好几个条件,就会告诉你Using where,或者是你用了索引查找,但是除了索引外,还需要用其他的字段进行筛选,这个也会使用到 Using where ,
比如SQL EXPLAIN SELECT * FROM t1 WHERE x2=’xxx’,这里的x2是没有建立索引的,所以此时他的执行计划如下:
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 4578 | 15.00 | Using where |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
针对t1表进行查询,用的是全表扫描方式,没有使用任何索引,然后全表扫描扫出来的是4578条数据,这个时候在extra里显示 Using where,意思是每条数据都用了where x2=’xxx’去进行筛选。最终filtered,过滤出来15条数据,大概就是说,从表里筛选出686条数据,就这个意思。
如果where条件里有一个条件是针对索引查询的,有一个列是普通列,类似SQL语句 :
EXPLAIN SELECT * FROM t1 WHERE x1=’xxx’ AND x2=’xxx’ 此时执行计划如下:
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ref | index_x1 | index_x1 | 458 | const | 250 | 18.00 | Using where |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
这个执行计划,针对t1表查询,先通过ref方式直接在index_x1索引里查找,跟const代表的常量去查找,然后查找出来250条数据,接着再用Using where代表的方式,去使用AND x2=’xxx’条件筛选,筛选后的数据比例是18%,最终查出来的数据大概是45条。
另外在多表关联的时候,有时关联条件并不是索引,此时就会用一种叫做join buffer的内存技术来提升关联性,比如下面的SQL语句:
EXPLAIN SELECT * FROM t1 INNER JOIN t2 ON t1.x2=t2.x2 ,他们的连接条件是x2是没有索引的,此时一起看看他的执行计划:
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 4578 | 100.00 | NULL |
| 1 | SIMPLE | t2 | NULL | ALL | NULL | NULL | NULL | NULL | 3472 | 1.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+
这个执行计划,要执行join,那么肯定先得查询t1表的数据,此时是对t1表直接全表查询,查询出4578条数据,接着就是对每条数据的x2字段的值,跑到t2表里去查对应的数据,进行关联。
但是此时因为t2表也没法根据索引来查,也是属于全表扫描,所以每次都得对t2表全表扫描一下,根据extra提示的Using where,就是根据t1表的每条x2字段的值去t2表查找对应的数据,然后此时使用join buffer技术,在内存里做一些特殊优化,减少t2表的全表扫描。
using where 和 using index condition,一个是根据条件查,一个是根据索引为条件查