作者:狼王\来源:https://www.cnblogs.com/power...1.前言应用开发初期,数据量较小,开发者更注重实现开发功能时的功能。随着生产数据的增长,很多SQL语句开始暴露性能问题,对生产的影响也越来越大。有时这些有问题的SQL可能是整个系统性能的瓶颈。二、SQL优化的一般步骤1、通过慢查询日志等定位执行效率低的SQL语句。2、说明分析SQL执行计划,需要重点关注type、rows、filtered、extra。从上到下打字,效率越来越高。ALL全表扫描;索引索引全扫描;范围索引范围扫描,常用词<、<=、>=、between、in等操作;ref使用非唯一索引扫描或唯一索引前缀扫描,返回单条记录,常出现在关系查询中;eq_ref与ref类似,不同的是它使用了唯一索引和主键相关查询;const/系统单条记录,系统会将匹配行中的其他列当作常量,比如主键或唯一索引查询;nullMySQL不访问任何表或索引,直接返回结果;虽然从上到下效率越来越高,但是根据成本模型,假设有两个索引idx1(a,b,c),idx2(a,c),SQL是“select*fromtwherea=1和bin(1,2)orderbyc";如果使用idx1,则类型为range;如果使用idx2,则类型为ref;当要扫描的行数,使用idx2大约是idx1的5倍或更多时,将使用idx1,否则使用idx2。ExtraUsingfilesort:MySQL需要额外的传递来确定如何按排序顺序检索行。排序是通过根据连接类型遍历所有行并为匹配WHERE子句的所有行保存排序键和行指针来完成的。然后对关键字进行排序,按照排序后的顺序检索行;使用临时表:使用临时表保存中间结果,性能特别差,需要优化;Usingindex:表示对应的select操作使用覆盖索引(CoveingIndex),避免访问表的数据行,效率好!如果同时出现usingwhere,说明不能通过索引搜索直接查询到符合条件的数据;Usingindexcondition:MySQL5.6后加入的ICP,usingindexcondition是利用ICP(indexpushdown),在存储引擎层进行数据过滤,而不是在服务层过滤,利用索引已有的数据来减少返回表的数据。3.showprofile分析了解SQL执行线程的状态和消耗时间。默认是关闭的,打开语句“setprofiling=1;”显示个人资料;显示查询#{id}的个人资料;4.tracetrace分析优化器如何选择执行计划。通过trace文件,可以进一步理解优惠券为什么选择A执行计划,而不是选择B执行计划。setoptimizer_trace="enabled=on";setoptimizer_trace_max_mem_size=1000000;select*frominformation_schema.optimizer_trace;5.确定问题并采取相应措施优化指标;优化SQL语句:修改SQL,IN查询切分,时间查询切分,基于上次数据过滤;使用其他实现方式:ES、数据仓库等;数据分片处理。三、场景分析1、最左匹配1)IndexKEY`idx_shopid_orderno`(`shop_id`,`order_no`)2)SQL语句select*from_twhereorderno=''从左到右查询匹配,使用order_no去Index,查询条件必须携带shop_id或index(shop_id,order_no)来切换前后顺序。2.隐式转换1)IndexKEY`idx_mobile`(`mobile`)2)SQL语句select*from_userwheremobile=12345678901隐式转换相当于对索引进行操作,会使索引失效。mobile是字符类型,使用的是数字,所以要使用字符串匹配,否则MySQL会使用隐式替换,导致索引失败。3.大分页1)IndexKEY`idx_a_b_c`(`a`,`b`,`c`)2)SQL语句select*from_twherea=1andb=2orderbycdesclimit10000,10;对于大分页的场景,可以优先考虑产品优化需求。如果不做优化,有如下两种优化方式:一种是把上次的最后一条数据,也就是上面的c,然后做"c
