当前位置: 首页 > 科技观察

带你了解MySQL执行计划

时间:2023-03-21 18:13:57 科技观察

前言在之前的面试过程中,当被问到执行计划的时候,很多童鞋都不知道是什么?甚至执行计划和执行时间也被认为是同一个概念。今天我们就来看看执行计划到底是什么?它是做什么用的?什么是执行计划?简单来说就是SQL在数据库中执行时的性能。通常用于SQL性能分析、优化等场景。在MySQL中使用explain关键字查看SQL执行计划。如下图//1.查询t_base_userselect*fromt_base_userwherename="andyqian";//2.查看上述语句的执行计划explainselect*fromt_base_userwherename="andyqian";执行查看上面2条语句,我们可以得到如下执行计划结果上面的执行计划是什么意思?参考价值是多少?上面执行计划给出的信息是:这个结果通过简单的语句扫描全表,共扫描1行,在t_base_user表中使用where条件过滤掉。发现语句没有走索引,为什么会这样?别着急,让我们进入下一节。阅读理解执行计划通过上面的内容,我们知道了什么是执行计划,也看到了什么是执行计划。现在让我们仔细看看每个属性在MySQL执行计划中代表什么。下面我们就来一一介绍和解释每个属性有哪些可选值,以及每个可选值的含义。id表示select操作表在查询中的顺序,按照从大到大的顺序执行。select_type:这个表示选择的类型,可选值有:SIMPLE(简单),type:这个属性表示访问类型,访问有很多种。最常见的包括以下几种:ALL(全表扫描)、index(索引扫描)、range(范围扫描)、ref(非唯一索引扫描)、eq_ref(唯一索引扫描)、(const)常量引用、访问速度依次由慢到快。其中:范围(range)常用与betweenand...,大于和小于这种情况。Tips:可以查看慢SQL是否使用了索引,使用了哪些索引。table:表示语句要查询的表possible_keys:顾名思义,该属性给出了查询语句,可能使用的索引,(比如某些字段上的索引名称)这里提供的仅供参考,不是实际的索引,也会导致possible_Keys不为null且key为空的现象。key:显示MySQL实际使用的索引,包括主键索引(PRIMARY),或自建索引的名称。key_len:表示索引使用的字节数,ref:连接匹配条件,如果使用主键索引,值为:const,对于全表扫描,为空值rows:扫描的个数rows,即扫描多少行,挖掘可以获得目标行数,一般大于返回的行数。通常,行数越小,效率越高,大部分SQL优化都是为了减小这个值的大小。注意:理想情况下,扫描行数理论上与实际返回行数相同,但这种情况极为罕见,比如关联查询,扫描行数会比返回行数大大增加)extra这个属性很重要,这个属性包含了SQL执行时的真实情况信息。如上,使用了“usingwhere”,意思是使用where过滤得到的值。常用的有:“Usingtemporary”:使用临时表“usingfilesort”:使用文件排序看到这里,我们应该已经发现,在第一步中,我们的SQLselect*fromt_base_userwherename="andyqian";没有使用索引,而且还是全表扫描,在数据量小的情况下,问题不会特别突出。如果数据量比较大,这是一个慢查询,会造成生产事故。现在我们修改一下,给name字段加一个索引,#addindexaltertablet_base_useraddindexidx_name(name);看看它的执行计划是干嘛的。你看,现在idx_name索引已经被使用了,它的类型是从All(全表扫描)到ref(非唯一索引)。别看,差别就这么一点点。当数据量很大的时候,它的作用就很大哦。数据结构本文演示的数据结构如下:#Createtablecreatetablet_base_user(oidbigint(20)notnullprimarykeyauto_increment,namevarchar(30)nullcomment"name",emailvarchar(30)nullcomment"email",ageintnullcomment"age",telephonevarchar(30)nullcomment“电话”,statustinyint(4)nullcomment“0无效,1有效”,created_atdatetimenullcomment“”,updated_atdatetimenullcomment“”)##新记录:insertintot_base_user(姓名,电子邮件,年龄,电话,created_at,updated_at)值("andyqian","andytohome@gmail.com",20,"15608411",now(),now());)***一个好的数据库表设计应该考虑从一开始就添加索引,而不是慢慢发现***SQL坏了,业务受到影响,我们来补救。其实在我的工作经历中,因为新建表或者新增字段后忘记添加索引,也造成了很多生产事故,至今记忆犹新!!!实际上,创建新索引是有一定原则的。建立什么样的索引?关于哪些领域,里面还有很多知识,下一篇会写,敬请期待!