MySQL优化的多种方法?
查询SQL避免全表扫描.而是具体字段--->1.节省资源,减少网络开销.2.可能用到覆盖索引,减少回表,提高查询效率.
1.避免在where子句中使用or来连接条件,而是使用union all --->1.使用or可能会导致索引失效,从而全表扫描;2.虽然mysql有优化器,出于效率与成本考虑,遇到or条件,索引还是可能失效的;
2.尽量使用数值替代字符串类型---主键(id):primary key优先使用数值类型int,tinyint | 性别(sex):0代表女,1代表男;数据库没有布尔类型,mysql推荐使用tinyint 理由:1.因为引擎在处理查询和连接时会逐个比较字符串中每一个字符;2.而对于数字型而言只需要比较一次即可;3.字符会3.降低查询和连接的性能,并会增加存储开销;
使用varchar(按实际长度存储)代替char--->char按声明大小存储,不足补空格,其次对于查询来说,在一个相对较小的字段内搜索,效率更高;
4.技术延伸,char与varchar2的区别?--->1.char的长度是固定的,而varchar2的长度是可以变化的。2.char的效率比varchar2的效率稍高!
5.Where中使用默认值代替null-->1.其实一般情况下,查询的成本高,优化器自动放弃索引的,2.如果把null值,换成默认值,很多时候让走索引成为可能,同时,表达意思清晰。
6.避免在where子句中使用!=或<>操作符--->使用!=和<>很可能让索引失效, 实现业务优先,即可使用
7.Inner join,left join,right join,优先使用inner join ---->三种连接如果结果相同,优先使用inner join,如果使用left join左边表尽量小。---->这是mysql优化原则,就是小表驱动大表,小数据集驱动大的数据集,从而让性能更优!
8.提高group by语句的效率---->先过滤数据,后分组 ---->理由:可以在执行到该语句前,把不需要的记录过滤掉!
9.清空表时优先使用truncate-->truncate table在功能上与不带where子句的delete语句相同:二者均删除表中的全部行.但truncate table比delete速度快,且使用的系统和事务日志资源少! | 对于由foreign key约束引用的表,不能使用truncate table,而应使用不带where子句的DELETE语句,由于truncate table不记录在日志中,所以它不能激活触发器。 truncate table不能用于参与了索引视图的表。
10.操作delete或者update语句,加个limit或者循环分批次删除--->1.降低写错SQL的代价 加个limit,删错也只是丢失部分数据,可以通过binlog日志快速恢复的. 2.SQL效率也许提高 SQL中加了limit 1, 如果第一条即命中目标return,没有limit的话,还会继续执行扫描表。 3.避免长事务 delete执行时,如果age加了索引,Mysql会将所有相关的行加写锁和间隙锁,所有执行相关行会被锁住,如果删除数量大,会直接影响相关业务无法使用! 4.数据量大的话,容易把CPU打满 如果你删除数据量很大时,不加limit限制一下记录数,容易把CPU打满,导致越删越慢,5.锁表:一次性删除太多数据,可能造成锁表,会有lock wait timeout exceed的错误,所以建议分批操作.
11.UNION操作符--UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的纪录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION. 如:select username,tel from user union select departmentname from department 这给SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。推荐方案:采用UNION ALL操作符替代UNION, 因为UNION ALL操作只是简单的将两个结果合并后就返回
12.批量插入性能提升---批量插入数据 insert into 表名 values(),(); --->理由:默认新增SQL有事务控制,导致每条都需要事务开启和事务提交,效率明显提升,达到一定量级,效果显著,时间成本控制!
13.表连接不宜太多 一般五个以内,索引不宜太多,一般五个以内--》1.阿里规范中,建议多表联查三张表以下2.关联的表个数越多,编译的时间和开销也就越大 3.每次关联内存中都生成一个临时表。3.应该把连接表拆开成较小的几个执行,可读性更高 | 1.索引并不是越多越好,虽其提高了查询的效率,但会降低插入和更新的效率。2.索引可以理解为一个就是一张表,其可以存储数据,其数据就要占空间;3.insert或update时有可能会重建索引,如果数据量巨大,重建将进行记录的重新排序,所以建索引需要慎重考虑,视具体情况来定; 4.索引表的数据是排序的,排序是要花时间的。
14.避免在索引列上使用内置函数: 例子:select *from user where brithday >= DATE_ADD(NOW(),INTERVAL 7 DAY); // 使用索引列上内置函数,索引失效。
15.组合索引--->排序时应按照组合索引中各列的顺序进行排序,即使索引中只有一个列是要排序的,否则排序性能会比较差。
16.复合索引最左特性--->1.创建复合索引 alter table employee add index idx_name_salary(name,salary) 2.满足复合索引的最左特性,哪怕只是部分,复合索引失效 select *from employee where name =”哪吒编程”; 3.没有出现左边的字段,则不满足最左特性,索引失效 select * from employee where salary =5000 4.复合索引全使用 按左侧顺序出现name,salary,索引失效 select *from employee where name = “哪吒编程” and salary = 5000; 5.虽然违背了最左特性,但MySQL执行SQL时会进行优化,底层进行颠倒优化 6.复合索引也称为联合索引,当我们创建一个联合索引时,如(k1,k2,k3),相当于创建了(k1),(k1,k2),(k1,k2,k3)三个索引,这就是最左匹配原则.联合索引不满足最左原则,索引一般会失效。
17.优化like语句--->模糊查询,程序员最喜欢使用like,但like可能会让索引失效。1.全模糊查询是无法优化的,一定要使用的话建议使用搜索引擎。
18.使用explain分析你SQL执行计划 1.type
19.一些其它优化的方式--->1.设计表的时候,所有表和字段都添加相应的注释。2.SQL书写格式,关键字大小保持一致,使用缩进。