MySQL查询优化

最近做项目遇到一些查询优化的问题,所以特意花了点时间研究了一下MySQL的查询优化,特此记录。

先说下遇到的问题。项目里有个sql,大概是这个样子的:

select tba.col... from tba where col1>'2017-06-01' and col1<'2017-06-30' and col2 in(select value from tbc where name='aaa') union all select tba.col... from tba left join tbb on tba.id=tbb.tba_id where tbb.col1>'2017-06-01' and tbb.col1<'2017-06-30' and tba.col2 in(select value from tbc where name='bbb') limit 2000
原先的sql是没有union all 后面的部分的,用着一致没问题,最近做了一些业务调整,所以sql也跟着动了一下。结果一上线,发现sql严重慢查(此处敲个钟,上线的sql最好在线上环境做个执行测试,没问题了再上),导致线上功能受影响。出了问题赶紧查,初步看了一下,tba和tbb的col1都是有索引的,并且各自的查询返回数据量最多也就十来万,应该也没啥问题。那问题到底出在哪里呢?又把sql捋了一遍,感觉会不会是子查询的问题。为了验证,我把子查询抽出来,将查询结果查出来作为条件传进sql,然后惊奇地发现查询速度一下就快了。上网查了一下,MySQL似乎做了这样一件事:先查出外部sql的结果,然后逐条代入子查询(这尼玛就是做了个交叉乘啊,有些弱智),最后导致sql查询异常慢。好吧,老老实实分步查吧。

然后分享一些索引优化的小知识:

1.联合索引有个最左匹配原则,即A+B+C组成一个索引,那么A或A+B或A+B+C的条件组合可以走索引,其他的都无法使用该索引。

2.如果sql只查询索引中包含的列,速度会快很多,因为此时数据库只需要从索引中取数据就够了,不需要要再扫表。像大数据量的分页查询就可以用这个思路进行优化。

3.查询条件的数据类型要准确,比如col1是字符型的,而你的sql写成select col... from tba where col1=11虽然也可以查出结果,但是这样是走不了col1上的索引的,需要写成where col1='11'这种形式才可以。

此外定期分析表和检查表说不定也有奇效,但是分析和检查表会锁表,最好在业务量较小的时候进行。

你可能感兴趣的:(数据库)