- 如何查看select语句是否进行了全表扫描
- sql优化
- 面试问题
1.如何查看select语句是否进行了全表扫描?
mysql中使用explain关键字
语法:
explain select * from t_collect
查询结果:
这里可以看到图中的“type”列的值为ALL说明全表扫描。
type解释:
表示MySQL在表中找到所需行的方式,又称“访问类型”。
常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index: Full Index Scan,index与ALL区别为index类型只遍历索引树
range:只检索给定范围的行,使用一个索引来选择行
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
如果想知道其他字段的含义请移步:https://www.cnblogs.com/xuanzhi201111/p/4175635.html
2.sql优化
通过上面的explain关键字咱们可以知道本条sql语句是否会全表扫描,那接下来接根据这个查询结果来查看sql语句是否被优化。
1.编写sql语句如下,根据cid查找,这里cid不是索引
explain select * from t_collect where cid = 2
结果:
由上图看type的值依旧为ALL,说明是全表扫描。
2.将cid设置为索引,继续查询
结果:
这里的type值为ref,说明用于索引查找,更高级的优化这里不再详细说明,希望我这里抛出的砖头能让你引出美玉。
3.面试问题
这里想引申一下很久之前自己面试的经历,之前面试的时候被面试官问过关于全表扫描的问题,但是当时自己回答的很不好,希望读者遇到类似的问题能轻松解答。
下面列举一个印象最深的一串问题:
如果将t_collect表中的cid字段和type字段创建为一个组合索引,组合索引的创建顺序是cid,type ;
即:ALTER TABLE `t_collect` ADD INDEX cid_type (cid,type);
1.如果查询条件为cid时select * from t_collect where cid = 1语句会不会全表扫描?
2.如果查询条件为type时select * from t_collect where type = 1语句会不会全表扫描?
3.如果select * from t_collect where type = 1 and cid = 1语句会不会全表扫描?
4.如果select * from t_collect where cid = 1 and type = 1语句会不会全表扫描?
所用表结果:
CREATE TABLE `t_collect` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`cid` int(11) DEFAULT NULL COMMENT '内容id',
`type` int(11) DEFAULT NULL COMMENT '类型 0:蜂品种;1:蜂产品;2:病虫害',
`state` int(11) DEFAULT NULL COMMENT '状态 0:取消;1:收藏',
`uid` int(11) DEFAULT NULL COMMENT '收藏人id',
`modifyTime` datetime DEFAULT NULL COMMENT '修改时间',
`createTime` datetime DEFAULT NULL COMMENT '收藏时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='收藏表';