性能优化步骤
- 首先我们通过查看数据库是什么以查询位置还是增删改为主,增删改的话就手动开启事务,并且批量提交数据。
- 如果是查询为主的话就开启慢查询日志
# 开启MySQL慢查询日志开关
slow_query_log=1
# 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2
慢查询日志会将超过设置时间的sql记录下来 3. 通过慢查询日志找到慢sql的id,用profiles查询每个阶段的耗时,可以有针对性的去优化 4. 之后通过explain执行计划看
- type字段:是否走了索引,没走索引尽量走索引,从好到坏分别是const、eq_ref、ref、range、index、all,all的话是查全表,尽量不要。
- possible_keys字段:指出MySQL能使用哪个索引在该表中找到行。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段是不是适合索引。
- key_len字段:可以通过长度的变化看出用了联合索引的哪些字段
- extra字段:会显示额外的信息,要注意的是排序:using index(索引排序)> Using filesort(缓冲区排序)
索引
最左前缀原则
简称最左原则,也就是想使用联合索引的时候,其最左边的那个字段必须存在,否则不能使用该联合索引。比如(name,age,class)做联合索引,where子句里必须有name,否则不能使用该联合索引,至于where子句里字段的顺序无所谓,where class ='class1' and age = 20 and name = 'Lin'也能使用该索引。
索引失效场景
部分失效
- 当出现范围查询,用的是
<、>的时候会出现右边索引失效,所以尽量使用<=、>=
完全失效
- 不符合最左原则的
- 字段使用函数或者进行运算的。这将会使优化器无法下手,导致索引失效
- 字符串类型字段不加引号。相当于用函数隐式转换了,会失效。
- 不等于。将全表检索
- 用了or并且字段中有没有索引的
- 用了like,%通配符在前面的,同时查询字段不覆盖索引的
- 查询数据占所有数据的比重比较大的,mysql直接查全表
索引设计原则
- 在数据量大、经常查询的表上尽量建立索引
- 在经常select、group、order的字段建立索引
- 唯一索引要建立在区分度高的字段
- 尽量建立联合索引
- 对较长的字段建立前缀索引
- 控制索引数量
- 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含 NULL值时,它可以更好地确定哪个索引最有效地用于查询。
SQL优化方案
insert优化
小数据量
- 主键顺序插入
- 用values批量插入
- 手动开启事务,一次性提交
大数据量
用load命令插入数据
-- 客户端连接服务端时,加上参数 -–local-infile
mysql –-local-infile -u root -p
-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
-- 执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/sql1.log' into table tb_user fields
terminated by ',' lines terminated by '\n' ;
delete优化
跟insert一样,采用批量删除
update优化
where采用索引,这样就会用行锁否则会用表锁
主键优化
主键要选择顺序增长的,尽量短,插入数据也要尽量顺序插入
排序优化
- 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
- 尽量使用覆盖索引。
- 多字段排序, 一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)。
- 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k)。
分组优化
- 还是走索引
limit优化
子查询(多表关联) + 覆盖索引,也就是先查询到需要筛选数据的主键,然后再进行数据子查询或者表关联查询到需要的具体数据
count优化
尽量使用count(*)
- count(*)不取值,按行累加
- count(1)不取值,填入1按行累加
- count(字段)取值,有时候需要判空(主键不需要判空,有约束不需要判空)
所以效率是count(*)=count(1)>count(字段)