关于SQL字符类型设置默认值NULL索引是否失效

背景:

在公司的项目中发现一个查询页面特别慢,查询10条数据用了26秒以上,看了下总数是 271622,也不多,况且分页是10条数据一页,应该有某个地方比较耗时,经过排查代码,发现是sql的问题,索引失效导致。
直接上图看耗时:
在这里插入图片描述

排查经过:

看调用的sql:

在这里插入图片描述

表结构:

pr表:

在这里插入图片描述

d表:

在这里插入图片描述
在这里插入图片描述

i表:

在这里插入图片描述

EXPLAIN调用的sql可以看到 i表的索引失效了:

在这里插入图片描述
但是如果是修改下sql,改成这样:在这里插入图片描述
EXPLAIN的结果是这样了,i表走了索引了,
在这里插入图片描述

由此可以得出结论:

如果是默认字段设置NULL默认值,但是在where后面的查询条件没有调用到该表的字段作为查询条件,那么索引是生效的。所以并不是所设置NULL默认值,并且表中该字段存在NULL的数据索引就会失效,但是平常建表的时候还是尽量给字段设置默认值吧。

另外讲讲:

Using temporary

Using temporary表示由于排序没有走索引、使用union、子查询连接查询、使用某些视图等原因(详见internal-temporary-tables),因此创建了一个内部临时表。注意这里的临时表可能是内存上的临时表,也有可能是硬盘上的临时表,理所当然基于内存的临时表的时间消耗肯定要比基于硬盘的临时表的实际消耗小。

Using filesort

如果问Using filesort是什么意思,大多数人应该会回答“基于硬盘的排序”或者“数据太多不适合内存,所以在硬盘上排序”。然而这些解释是错误的。

Using filesort仅仅表示没有使用索引的排序,事实上filesort这个名字很糟糕,并不意味着在硬盘上排序,filesort与文件无关。因此消除Using filesort的方法就是让查询sql的排序走索引。

filesort使用的算法是QuickSort,即对需要排序的记录生成元数据进行分块排序,然后再使用mergesort方法合并块。其中filesort可以使用的内存空间大小为参数sort_buffer_size的值,默认为2M。当排序记录太多sort_buffer_size不够用时,mysql会使用临时文件来存放各个分块,然后各个分块排序后再多次合并分块最终全局完成排序。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值