查看SQL执行计划,重点关注下面三个字段
1)type列,连接类型。一个好的SQL语句至少要达到range级别。杜绝出现all级别。
2)key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式。
3)key_len列,索引长度。
例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了,如果数值较多,产生的消耗也是比较大的
不要查*,只查询所需要的字段
or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时 候)的方式来代替“or”会得到更好的效果。
union和union all的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。当然,union all的前提条件是两个结果集没有重复数据。
select id,name from product limit 866613, 20可以优化成select id,name from product where id> 866612 limit 20
优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的id是866612。
在一些用户选择页面中,可能一些用户选择的时间范围过大,造成查询缓慢。主要的原因是扫描行数过多。这个时候可以通过程序,分段进行查询,循环遍历,将结果合并处理进行展示。
对于null的判断会导致引擎放弃使用索引而进行全表扫描
例如LIKE“%name”或者LIKE“%name%”,这种查询会导致索引失效而进行全表扫描。但是可以使用LIKE “name%”。
使用全文索引可以解决LIKE“%name”或者LIKE“%name%”这个问题
创建全文索引的SQL语法是:
ALTER TABLE `dynamic_201606` ADD FULLTEXT INDEX `idx_user_name` (`user_name`);
使用全文索引的SQL语句是:
select id,fnum,fdst from dynamic_201606 where match(user_name) against(‘zhangsan’ in boolean mode);
注意:在需要创建全文索引之前,请联系DBA确定能否创建。同时需要注意的是查询语句的写法与普通索引的区别。
比如:
select user_id,user_project from user_base where age*2=36;
中对字段就行了算术运算,这会造成引擎放弃使用索引,建议改成:
select user_id,user_project from user_base where age=36/2;
where子句中出现column字段的类型和传入的参数类型不一致的时候发生的类型转换,建议先确定where中的参数类型。
举列来说索引含有字段id、name、school,可以直接用id字段,也可以id、name这样的顺序,但是name;school都无法使用这个索引。所以在创建联合索引的时候一定要注意索引字段顺序,常用的查询字段放在最前面。
尽量使用inner join,避免left join,因为参与联合查询的表至少为2张表,一般都存在大小之分。如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表,但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表,利用小表去驱动大表