Explain:你见过这样的Sql吗?( 四 )


文章插图
2)using where:使用where语句来处理结果,并且查询的列未被索引覆盖

Explain:你见过这样的Sql吗?

文章插图
3)using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围;
Explain:你见过这样的Sql吗?

文章插图
4)using temporary:mysql需要创建一张临时表来处理查询 。出现这种情况一般是要进行优化的,首先是想到用索引来优化
user.name没有索引,此时创建了临时表来distinct
Explain:你见过这样的Sql吗?

文章插图
address.name建立了idx_name索引,此时查询时extras是using index,没有用临时表
Explain:你见过这样的Sql吗?

文章插图
5)using filesort:将用外部排序而不是索引排序 , 索引较小时从内存排序,否则需要在磁盘完成排序 。这种情况下一般也是要考虑使用索引来优化的
actor.name未创建索引,会浏览actor整个表,保存排序关键字name和对应的id,然后排序name并检索行记录,
Explain:你见过这样的Sql吗?

文章插图
address.name建立了idx_name索引 , 此时查询时extra是using index
Explain:你见过这样的Sql吗?

文章插图
6)Select tables optimized away:使用某些聚合函数(比如max、min)来访问存在索引的某个字段是
Explain:你见过这样的Sql吗?

文章插图
附:1、派生表
派生表 , 是用于存储子查询产生的结果的临时表,这个子查询特指 FROM 子句 里的子查询,如果是出现在其它地方的子查询 , 就不叫这个名字了,所以本质上来说 , 派生表也是临时表 。
2、物化表
物化表,也是用于存储子查询产生的结果的临时表,这个子查询特指 WHERE 子句中查询条件里的子查询 。
前导列:
前导列 , 就是在创建复合索引语句的第一列或者连续的多列 。比如通过:CREATE INDEX comp_ind ON table1(x, y, z)创建索引,那么x,xy,xyz都是前导列,而yz,y,z这样的就不是 。
3、dual表
Dual表其实就是一个虚表,你可以在没有表的情况下指定这个虚拟的表名 。
4、int(1)、int(2)、int(3)...int(10)有什么区别?
不知道大家对于上面ken_len列的计算是否有疑问,为什么像int这类数据类型就是4字节,而不是int(num)中的num字节接下来就给大家解释一下 。
Mysql中int是占4个字节,那么对于无符号的int , 最大值就是2^32-1 = 4294967295
int后面的数字不能表示字段的长度,int(num)一般加上zerofill才有效果,它能够实现当该字段不足num位时补0的效果 。
下面我们给出一个例子:
首先我们创建一个测试表
CREATE TABLE `intTest` (`id` int(1) ZEROFILL UNSIGNED NOT NULL,`test` int(1) UNSIGNED ZEROFILL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;测试表中id列,test列是一个无符号整型,且设置的是int(1),那么他是不是意味着不能插入4294967295这个4字节的最大数字,接下来我们就插入4294967295试一下:
[SQL]INSERT INTO `inttest` VALUES(4294967295,4294967295);
受影响的行: 1
时间: 0.013s
Explain:你见过这样的Sql吗?

文章插图
可以看到成功插入,没有报错,也就说明int(1)并没有限制只有1个字节 , 接下来我们把test字段的int中的位数改成5,id列不变并都插入数字1看一下有什么效果,
Explain:你见过这样的Sql吗?

文章插图
可以看到test列为int(5),所以在不满足5位的时候会在前面补零,因为我们加上了zerofill属性,而id列我们设置了int(1)他就不会补零 。这里面说明一下;为什么用命令行看:因为在navicat中他是不显示这个零填充(小编的navicat是显示不出来的)
Explain:你见过这样的Sql吗?

文章插图

Explain:你见过这样的Sql吗?

文章插图
这里面还有一个小细节:其实我们在给某一列增加zerofill属性的时候 , mysql会自动增加一个unsigned属性,我们可以看一下:
我们新增加一列test1:
ALTER TABLE `intTest` add COLUMN `test1` int(3) ZEROFILL;向test1中插入负数
INSERT INTO `inttest` VALUES(2,2,-2);此时会发生报错;因为小编的mysql处于严格模式下

推荐阅读