Mysql性能优化神器详解。彻底的Mysql性能优化神器讲解。清晰的前言数据准备创建数据表插入数据explain命令使用select_typetyperowsrefextra总结前言SQL语句在不同的人手里会写成不同的形式,比如经常遇到的慢SQL查询,这时候往往需要针对SQL进行优化.为了保证SQL语句的高效运行,Mysql提供了Explain命令,用于分析SQL语句的语义,供开发者针对SQL进行优化。数据准备为了便于整个流程的执行,首先创建测试数据。创建数据表SQL的执行涉及到单表和多表的联合执行。这次创建了两个表来模拟这种情况。more多张表联合执行,两张表的执行计划是一样的。CREATETABLE`users`(`id`int(11)NOTNULLAUTO_INCREMENT,`create_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMP,`name`varchar(20)NOTNULLDEFAULT''COMMENT'username',`sex`tinyint(4)NOTNULLDEFAULT'1'COMMENT'性别',`phone`varchar(11)NOTNULLCOMMENT'电话号码',`desc`varchar(200)NOTNULLDEFAULT''COMMENT'介绍',主键(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT'usertable';CREATETABLE`order`(`id`int(11)NOTNULLAUTO_INCREMENT,`phone`varchar(11)NOTNULLCOMMENT'phonenumber',`name`varchar(20)NOTNULLCOMMENT'username',primarykey(`id`))ENGINE=InnoDBdefaultCHARSET=utf8COMMENT'order';为方便插入数据这次不再使用SQL语句,而是使用存储过程创建数据,简单、快速、方便。#Createstoredprocedurecreateprocedureinsert_user_data()begindeclareiint;declarenamevarchar(20);declarephone_numvarchar(11);set@SURNAME='WangLiZhangLiuChenYangHuangZhaoWuZhouXuSunMaZhuHuGuoHeGaoLinLuoZhengLiangXieSongTangWeiXuHanFengDengCaoPengZengXiaoTianDongPanYuanYuJiangCaiYuDuYeChengSuWeiLuDingRenShenYaoLuJiangCuiZhongTanLuWangFanJinShiLiaoJiaXiaWeiFuFangBaiZouMengXiongQinQiuJiangYinXueYanDuanLeiHouLongShiTaoLiHeGuMaoHaoGongShaoWanQianYanQinWuDaiMoKongXiangtang';set@NAME='DanJuyi'smusicbookQianYunalsofromgenerationtoWeiYouJunXiuJianAoErYuanGuangLanDongIcecoldLingNingFanKaiChuLiqinThousandsofflowers,halfofChina,Nanbo,andfriends,XiangJuntingandZheJia,thestrongcity,thesummernight,theskyisaswonderfulasthewonderfulchild,JiGuyu,AnWanchen,HanXun,ErYaoshan,LanJun,Qiaoping,Youkang,Jiankai,Hongqiang,Tongyan,BinPeng,Reminiscence,RemembranceandPityHateXiMuChengqingMinWenXinXuanXuHaoMingYiXinYingChunYuJinXiaoHanShengJingQingZhiManPengLangJieSongFengBaiRouLiuGeTaoMengKaiHuaiZhengShuiPeiBoZeCleanYangJiPuHaoHaiTaoRunHanYuanPuPuHanLingCanYanYeRanXuanYuXiYiYuShanZhenLiQiQinYuRuiYaoJinPuChiHaoHopeTrueRuiBiLeiXiangQiBingChengLiZhuXiaoZiShaoJingLuQunCuiHanZhiHangLiangFuZhiCangYuanRuomaoRonglianHanLingxuanRongLanruiLeiweibutterflyseekssincerewordsGuHaoFusurpassesXuanHuiDaYuandrunkJinXinJinWenYanYaYuXueLinFrostDewQingJingJingJingFengFlyingFragranceChiQianGaoHongpengHeli';seti=1;whilei<100000doSETphone_num=concat('1',substring(cast(3+(rand()*10)%7ASchar(50)),1,1),right(left(trim(cast(rand()ASchar(50))),11),9));setname=concat(substr(@surname,floor(rand()*length(@surname)/3+1),1),substr(@NAME,floor(rand()*length(@NAME)/3+1),1),substr(@NAME,floor(rand()*length(@NAME)/3+1),1));insertintousers(create_time,name,sex,phone,`desc`)values(now(),名称,rand()*1,phone_num,'测试');插入`order`(phone,name)values(phone_num,name);seti=i+1;endwhile;end#执行存储过程调用insert_user_data();#删除存储过程dropprocedureifexistsinsert_user_data;创建存储过程后,如果需要修改,可以直接使用删除的存储过程,然后重新创建。explain命令使用explain执行命令explainselect*fromuserswhereid=1\G;显示如下:***************************1.行****************************id:1select_type:SIMPLEtable:userspartitions:NULLtype:constpossible_keys:PRIMARYkey:PRIMARYkey_len:4ref:constrows:1filtered:100.00Extra:NULL1rowinset,1warning(0.00sec)一共有12个字段,每个字段的含义如下:id:每个查询statement会生成一个标识符,执行顺序为执行select_type:查询的类型,包含各种类型的跳转toselect_typetable:查询的表名,包括关联的表信息partitions:匹配的分区类型:表示Mysql在表中查找需要的行的方式,这里是使用索引的方式。typepossible_keys:Theindexkeythatmaybeusedbythequerystatement:查询语句实际使用的索引key_len:表示索引使用的字节数。注意显示的是索引字段中的最大可能长度,而不是实际长度需要阅读以找到所需的记录extra:此列的查询中包含的其他附加详细信息。有些字段的类型比较多,下面会详细说明。select_type用于表示每一种查询类型,常用类型如下:SIMPLE:最简单的查询方式,单表查询,不包括UNION和子查询,如select*fromuserswhereid=1PRIMAPY:表示次要query是最外层query。当有子查询时显示。解释select*fromuserswherephone=(selectphonefromorderwhereid=10);UNION:表示第二次查询是UNION的第二次或后续查询方式,查询语句中有union关键字explainselect*fromuserswhereid=10unionselect*fromuserswhereid=20;DEPENDENTUNION:UNION中的第二条或后续查询语句依赖于外层查询UNIONRESULT,UNION的结果。SUBQUERY:子查询中的第一个SELECT.DEPENDENTSUBQUERY:子查询中的第一个SELECT依赖于外部查询。当子查询依赖于外部查询结果时,会显示explainselect*fromuserswherephone=(selectphonefromorderwhereid=users.id)andid=10;。这里最常见的类型是SIMPLE类型,我们经常使用的多表查询也是SIMPLE类型。比如解释select*fromusersleftjoinorderoonusers.phone=o.phonewhereusers.id=10typetype字段帮助我们定位查询是否高效,是全表扫描还是索引扫描。不同的类型代表不同的性能,顺序如下:ALL
