sql优化
目录
优化建议
select优化
- sql语句中in值不能过多, 对于连续的值建议用between
- select语句 不要使用 * ,需指明字段
- 只查询一条数据的时候,用limit 1
- 不要再where子句中对字段进行null 判断
在mysql中会自动判断数据的分布情况,判断数据中null多还是not null多然后决定走不走索引 - 不要在where子句中进行表达式操作
- 对于联合索引,要遵循最左原则
多列联合索引,字段可以少,但索引的顺序要规范 - 尽量使用inner join 避免left join
mysql在没有其他过滤条件的情况下,inner join 会自动选择小表驱动大表,left join 遵循左表驱动右表 - 注意范围查询
对于联合索引,如果存在范围查询(between、>、<)等条件,会造成后面的索引失效,在业务允许的情况下使用≥、≤ 不影响索引使用 - 不要使用%前缀查询
- 在where子句中使用or连接条件,如果or连接的条件有一方没有索引,会导致索引失效
- 不要在where子句中进行函数操作(待复议)
- 字符串类型的字段需要加引号,不然会导致自动进行隐式转换,索引失效
- order by排序时,建议使用有索引的字段进行排序
- count优化
速度: count( ) > count(1) > count(字段)
inndb引擎的使用如下 (MyIASM默认存了数据总数,所以效率最高)
1:count(字段):遍历整张表 会把每一行的字段值取出来,然后返回
2:count(1): 便利整张表,但不取值,对于返回的数据,放入1进去.然后累加
3:count():inndb引擎,特意做了优化,不会取出值,直接服务层进行累加
insert优化
- 批量插入时,建议手动提交事务
start transaction; 执行sql; commit;
update优化
-
innodb引擎使用update时,会有行锁/表锁两种模式, 如果where 字段没有索引的时候会升级成表锁
update table set xx=1 where name=xx (name没有索引,此时是表锁)
update table set xx=1 where id=xx (id有索引,此时是行锁)
建表优化
- 创建表时,使用统一的编码
mysql多表联查时,如果表的字符集不一样,会有一个数据类型转换的过程.
例如 utf8 与utf8mb4前者是3字节unicode编码,后者是4字节unicode编码. 此时如果多表查询,则索引会失效
mysql
explain关键字分析
oracle重建索引
analyze table table_name compute statistics;