-- 匹配左前缀
select * from T where a=''; -- Y
select * from T where b=''; -- N
-- 匹配列前缀
select * from T where a like 'x%'; -- Y
select * from T where a like '%x'; -- N
select * from T where b like 'x%'; -- N
-- 全值匹配
select * from T where a='' and b='' and c=''; -- Y
select * from T where c='' and b='' and a=''; -- Y
-- 匹配范围值
select * from T where a between '' and ''; -- Y
select * from T where b between '' and ''; -- N
-- 全值匹配 + 范围匹配
select * from T where a='' and b between '' and ''; -- Y
select * from T where b='' and c between '' and ''; -- N
select * from T where a between '' and '' and b=''; -- N
很多高性能的应用都会对关联查询进行分解,就是可以对每一个表进行一次单表查询,然后将查询结果在应用程序中进行关联,很多场景下这样会更高效, (4)优化LIMIT分页 在系统中需要分页的操作通常会使用limit加上偏移量的方法实现,同时加上合适的order by 子句。如果有对应的索引,通常效率会不错,否则MySQL需要做大量的文件排序操作。
方法四:建立复合索引 acct_id和create_time select * from acct_trans_log WHERE acct_id = 3095 order by create_time desc limit 0,10
注意sql查询慢的原因都是:引起filesort
(5)分析具体的SQL语句 1、两个表选哪个为驱动表,表面是可以以数据量的大小作为依据,但是实际经验最好交给mysql查询优化器自己去判断。 例如: select * from a where id in (select id from b ); 对于这条sql语句它的执行计划其实并不是先查询出b表的所有id,然后再与a表的id进行比较。 mysql会把in子查询转换成exists相关子查询,所以它实际等同于这条sql语句:select * from a where exists(select * from b where b.id=a.id );
最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整;
=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式;
得分点
慢查询日志
参考答案
标准回答
慢查询优化的前提是定位到响应慢的SQL,这可以通过启用慢查询日志来实现。默认情况下,MySQL并不启用慢查询日志,我们需要手动开启这个参数。通过日志定位到慢查询的SQL之后,我们可以使用EXPLAIN语句来分析这个SQL,进而发现问题所在。导致慢查询的原因有很多,下面列举几种常见的原因,以及对应的解决方案:
向数据库请求了多余的数据:
很多时候,我们的SQL返回的结果会超出我们的需要,例如实际上它返回了更多的行,而我们只要其中的一部分。又或者我们要求返回所有的列,实际上却只有其中少数的列。对于这类问题,我们可以通过LIMIT控制返回的行数,尽量不用
SELECT *
避免查询到过多的列。SQL复杂导致无法利用缓存:
处于业务的需要,我们经常会写出比较复杂的SQL,这自然包括复杂的关联查询。由于复杂SQL返回的结果涉及多张表、多个条件、甚至各种函数,这样的SQL每次返回的结果势必不同,所以很难利用到数据库的缓存。如果我们将复杂SQL进行拆分,变成若干简单的SQL,那么其中有些SQL由于条件不变,就可以利用到数据库的缓存了,从而让查询效率得以提升。
没有选择正确的索引:
我们都知道,创建索引是提高查询效率的一个常用手段,事实上我们也经常会这样做。但是,很多时候我们创建了索引,通过EXPLAIN查看会发现并没有走这个索引,最终导致SQL执行变慢。所以,不是把索引创建出来就算完成任务,还要分析索引的选择性,根据业务条件不断的优化索引,从而增加索引的命中率。
加分回答
除上述优化的方向之外,SQL中还有很多地方都有优化的空间,例如COUNT()、关联查询、子查询、GROUP BY、LIMIT、UNION等。总体来说,不同的情况要区别对待,但所有优化的背后是基于慢查询日志的定位。另外,为了能够发现问题的本质,还需要对MySQL执行查询的过程有所了解:
延伸阅读
B+树索引是基于B+树构建出来的有序结构,只有利用上它的有序性才能提高查询的效率。若不满足有序性这个前提,则在这个索引中的查询是离散的,其效率反而更低。查询优化器对索引的选择性,被称为最左前缀原则。
假设有如下一张表:
假设idx_union的叶子节点数据如下:
该索引的选择性示例如下: