#架构师师长#来点干货!SQL优化和诊断,没内鬼( 二 )
页面搜索严禁左模糊或者全模糊 , 如果需要请走搜索引擎来解决
#反例(耗时78.843s)EXPLAINselect*fromtask_resultwheretaskidLIKE'%tt600e6b601677b5cbfe516a013b8e46%'LIMIT1;#正例(耗时0.986s)select*fromtask_resultwheretaskidLIKE'tt600e6b601677b5cbfe516a013b8e46%'LIMIT1###########################################################################对正例的Explain1SIMPLEtask_resultrangeadapt_idadapt_id9899100.00Usingindexcondition#对反例的Explain1SIMPLEtask_resultALL3362855411.11Usingwhere#说明task_result表为生产环境的一个表 , 总数据量为3400万 , taskid是一个普通索引列 , 可见%%这种匹配方式完全无法使用索引 , 从而进行全表扫描导致效率极低 , 而正例通过索引查找数据只需要扫描99条数据即可复制代码避免SQL中对where字段进行函数转换或表达式计算#反例select*fromtask_resultwhereid+1=15551;#正例select*fromtask_resultwhereid=15550;###########################################################################对正例的Explain1SIMPLEtask_resultconstPRIMARYPRIMARY8const1100.00#对反例的Explain1SIMPLEtask_resultALL33631512100.00Usingwhere#说明其实在知道了有SQL优化器之后 , 我个人感觉这种普通的表达式转换应该可以提前进行处理再进行查询 , 这样一来就可以用到索引了 , 但是问题又来了 , 如果mysql优化器可以提前计算出结果 , 那么写sql语句的人也一定可以提前计算出结果 , 所以矛盾点在这个地方 , 导致5.7版本以前的此种情况都无法使用索引吧 , 未来可能会对其进行优化使用ISNULL()来判断是否为NULL值说明:NULL与任何值的直接比较都为NULL
#1)NULL<>NULL的返回结果是NULL , 而不是false 。 #2)NULL=NULL的返回结果是NULL , 而不是true 。 #3)NULL<>1的返回结果是NULL , 而不是true 。 多表查询我所在的公司基本禁止了多表查询 , 那如果必须使用到的话 , 我们可以一起参考一下阿里的编码规范
Eg:超过三个表禁止join 。 需要join的字段 , 数据类型必须绝对一致;多表关联查询时 , 保证被关联的字段需要有索引
明明有索引为什么还走全表扫描之前回答一些面试问题的时候 , 对某一个点的理解出现了偏差 , 即我认为只要查询的列有索引则一定会使用索引去Push数据
然而实际上不仅仅是这样 , 真正应该是:针对查询的数据行占总数据量过多时会转化成全表查询
那么这个过多指代的是多少呢?
我的测试结果是50% , 但个人认为MySQL优化器不会完全纠结于行数区分是否全表 , 而是有很多其他因素综合考虑发现全表扫描的效率更高等等 , 所以充分认识到该问题即可
count(*)还是count(id)阿里的Java编码规范中有以下内容:
【强制】不要使用count(列名)或count(常量)来替代count(*)
count(*)是SQL92定义的标准统计行数的语法 , 跟数据库无关 , 跟NULL和非NULL无关 。
说明:count(*)会统计值为NULL的行 , 而count(列名)不会统计此列为NULL值的行
字段类型不同导致索引失效阿里的Java编码规范中有以下内容:
【推荐】防止因字段类型不同造成的隐式转换 , 导致索引失效
实际上数据库在查询的时候会作一层隐式的转换 , 比如varchar类型字段通过数字去查询
#正例EXPLAINSELECT*FROM`user_coll`wherepid='1';type:refref:constrows:1Extra:Usingindexcondition#反例EXPLAINSELECT*FROM`user_coll`wherepid=1;type:indexref:NULLrows:3(总记录数)Extra:Usingwhere;Usingindex#说明pid字段有相应索引 , 且格式为varcharTips自建数据表进行测试
CREATETABLE`student`(`id`bigint(20)NOTNULLAUTO_INCREMENTCOMMENT'主键',`name`varchar(255)NOTNULL,`class`varchar(255)DEFAULTNULL,`page`bigint(20)DEFAULTNULL,`status`tinyint(3)unsignedNOTNULLCOMMENT'状态:0正常 , 1冻结 , 2删除',PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=0DEFAULTCHARSET=utf8mb4【#架构师师长#来点干货!SQL优化和诊断,没内鬼】插入数据
推荐阅读
- 「电子商务」今日干货!2020年淘宝电商月入6000难吗
- [华为]有朋友问我“JAVA全栈”、“互联网架构师”和“JAVAEE”到底是什么?
- 三星Galaxy@高通和华为水平其实差不多,网友用ARM架构“搭积木”形象比喻!
- 科技俱乐部3架构,AMD证实X570和B550芯片组将支持下一代Zen
- 鹰飞国际注册新西兰公司的基本架构
- 「自媒体」自媒体运营即将干货分享,助力你自媒体创业,摆脱打工困局!
- 『显卡』RTX 3080ti正式曝光,全新架构性能不再“挤牙膏”,价格太感人!
- 「Java」只因不会Java性能优化,我与年薪百万的架构师就差了这一份PDF。
- 「职场老何」深度干货:如何从小公司跳槽去大公司?是我从小公司跳槽到世界500强的利器!
- [java互联网架构]into select语句,同事被开除了!,因用了Insert