SQL语句的优化

1、SQL的执行顺序

2、基础的SQL优化

    2.1、查询SQL尽量不要使用select *,而是具体到字段

    2.2、避免在where子句中使用or来连接条件

    2.3、使用varchar代替char

    2.4、尽量使用数值代替字符串类型

    2.5、查询尽量避免返回大量的数据

    2.6、使用explain查看SQL语句的执行计划

    2.7、是否使用了索引及其扫描类型

    2.8、创建name字段的索引

    2.9、优化like语句

    2.10、字符串怪现象

    2.11、索引不宜过多,一般在五个以内即可

    2.12、索引不适合建在有大量重复数据的字段上

    2.13、where限定查询的数据

    2.14、避免在索引上使用内置函数

    2.15、避免在where子句中使用表达式操作和!=后<>操作符

    2.16、去重distinct过滤字段要少

    2.17、where中使用默认值代替null

3、高级SQL优化

    3.1、批量插入使得性能提升

    3.2、批量删除优化

    3.3、提高group by语句的效率

    3.4、符合索引最左原则

    3.5、排序字段创建索引

    3.6、删除冗余和重复的索引

    3.7、不要有超过5个以上的表的连接

    3.8、inner join    left join  right join 优先考虑inner join

    3.9、in 子查询的优化

    3.10、尽量使用union all 代替union

2、基本的SQL优化

2.1查询SQL尽量不要使用select *,而是具体到字段

解释:

       字段过多时一个表可以达到100多个字段甚至跟多,所以我们只需要取自己想要的字段,节省资源,减少网络开销

       select *  进行查询时可能不会用到索引而走全表扫描

2.2、避免在where子句中使用or来连接条件

解释:  查询ID为1或者薪水为5000的用户

反例:select * from student where ID=1 or  salary =5000;

正例(使用union all):select * from student where ID=1  union  all 

                                       select * from student where salary =5000;

使用or很有可能会使索引失效,从而走全表扫描(or不确定性)

2.3、使用varchar代替char

解释: varchar会按照内存的实际长度存储,存储空间小,可以节省存储空间

            char 按照声明大小存储,不足的补空格

            其次对于查询来说在一个相对较小的字段内搜索效率更高

2.4、尽量使用数值代替字符串类型

解释:主键(id) primary key有限考虑使用数值类型的int

           性别(sex)0代表女,1代表男,数据库没有布尔类型,MySQL推荐使用tinyint

           支付方式(payment)1代表现金,2代表微信,3代表支付宝,4代表信用卡

          服务状态    1代表开启,2代表暂停,3代表停止

          商品状态     1代表上架,2代表下架,3代表删除

2.5、查询尽量避免返回大量的数据

解释:如果查询返回的数据量很大就会造成查询时间过长,网络传输的时间过长,通常采用分页方式,一页习惯10/20/30条

2.6、使用explain查看SQL语句的执行计划

解释:explain主要看SQL是否使用了索引

2.7、是否使用了索引及其扫描类型

解释;system(只有一条记录)>const(针对主键或唯一建)> eq_ref(使用唯一索引)>ref(使用非唯一索引)>range(索引范围扫描)>index(索引全扫描)>all(全表扫描)

2.8、创建name字段的索引

解释: alter table  student add index index_name(Name);

2.9、优化like语句

解释:     反例:explain   select  id,name from student where name like '%1';

             正例:explain   select  id,name from student where name like '1%';

2.10、字符串怪现象

解释:未能正确的使用索引,

              name=123(不会走索引,类型不匹配,MySQL会做隐式类型转换)

              name ='123'(会走索引)

2.11、索引不宜过多,一般在五个以内即可

解释:索引过多会降低插入和更新的效率  

2.12、索引不适合建在有大量重复数据的字段上

解释:比如sex字段,SQL优化器是根据表中的数据量来优化的,如果索引列还有大量的重复数据,MySQL查询优化器推算发现不走索引的成本更低,很可能就不走索引了

2.13、where限定查询的数据

解释:表中就只有一个男的

    反例:select  id,name from student where  sex='男'

    正例:select  id,name from student where id=1 and sex='男';

2.14、避免在索引上使用内置函数

2.15、避免在where子句中使用表达式操作和!=后<>操作符

解释:反例:explain select * from student where id+1-1=+1;

          正例:explain select *from student where id = 1=1-1;

         使用 !=后<>操作符很有可能会使索引失效

2.16、去重distinct过滤字段要少

2.17、where中使用默认值代替null

3、高级SQL优化

3.1、批量插入使得性能提升

解释:insert 语句时避免一条一条的插入,可以一次性插入想要的语句

          默认新增SQL有事务控制,导致每条都需要开启事务和提交事务,而批量处理只需一次事务的开启和提交,从而提高速度

3.2、批量删除优化

解释:避免同时修改或删除过多的数据,因为会造成CPU利用率过高,造成锁表的操作

反例:delete from student where id<100000;

           for(User user:list){

                       delete from student;

                       }

正例:delete from student where id between 500 and 1000;

           for(User user:list){

                       delete from student where id <500;

                       }

3.3、提高group by语句的效率

解释:可以考虑先过滤在分组(其实时where和having的区别)

    where在group by 之前使用

    having在group by之后使用,而且having过滤的一般是组合函数(count,avg,min,max,sum)

3.4、符合索引最左原则

解释:创建复合索引

alter table student add index index_name_saraly(name,saraly)

1.满足复合索引的左侧顺序,哪怕只是一部分,索引生效

          select * from  student where name='name1';

2.没有满足最左原则,索引失效

           select * from  student where saraly =3000;

3,复合索引全使用

            select * from  student where name='name1' and saraly=3000;

             select * from  student where saraly=3000 and name='name1';(虽然违背了最左原则,但MySQL会进行优化)

3.5、排序字段创建索引

解释:什么样的字段才需要创建索引呢,原则就是where和order by中常用的字段就创建索引

3.6、删除冗余和重复的索引

解释:show index from student

         创建索引:alter table student add  index index_name(name);

        删除student表的index_name索引:drop index index_name on student;

                                                                  alter table student drop index index_name;

       

3.7、不要有超过5个以上的表的连接

3.8、inner join    left join  right join 优先考虑inner join

3.9、in 子查询的优化

3.10、尽量使用union all 代替union

解释:union和unionall的区别是,union会自动去掉多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复
          union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序 union在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION

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