MySQL-SQL优化
insert
-
使用批量插入
当有多个insert语句时 使用批量插入,如果insert语句太多(例如超过一万条)建议分批插入(例如一次插入一千条,具体看情况)
-
手动事务提交
-
主键顺序插入
手动一次性插入大批量数据时,使用insert插入新能比较低。建议使用load命令进行插入
主键
页分裂
InnoDB存储引擎结构
页中间存储行数据,每一页包含了2-N行数据,根据主键排序
主键乱序插入会导致页分裂(申请新的数据页,讲数据页内的数据进行移动,并修改链表指针 保证有序)
页合并
当删除一条记录时,实际上记录物理上没有被删除,只是被标记为删除,它的空间可以使用
当页中的数据删除记录打到阈值(50%),会查看前一页或者后一页的数据是否能合并成一页已优化空间使用
尽量降低主键的长度
尽量使用自增主键
避免对主键的修改
order by
-
using file sort :通过表的索引或者全表扫描,读取满足条件的数据行,在排序缓冲区中完成排序操作(效率低)
-
using index :通过有序索引直接返回有序数据(效率高)
优化
根据orderby字段建立索引(指定顺序,升序,降序)
多字段排序时,必须遵循最左匹配原则
不可避免出现file sort时可以适当增加排序缓冲区大小
group by
与order by 差不多
limit
当偏移量过大时会出现慢查询,
例如 limit 2000000,10 ,mysql会找到200000010 条 数据,但是只返回后十条数据,会产生很多不必要的回表操作
优化
使用覆盖索引加子查询进行优化
(从业务上考虑偏移量过大存在刷数据问题,存在刷数据问题可以设置偏移量阈值,超过这个阈值直接返回空 例如:京东淘宝的商品列表页)
count
count(*)
innoDB引擎会加载所有的数据然后自己进行累加,效率上讲会不高
MyISM中维护了表大小的字段,效率会高
使用count时建议使用count(*) 或者count(1),count(字段)操作InnoDB会取值返回给服务层进行累加,且不会统计null 的值
update
InnoDB中的行锁是针对索引加的锁,如果更新操作查找的字段没有走索引会进行锁表,性能比较低