SQL优化

1. 记录慢SQL 

开启慢SQL日志:

SET GLOBAL slow_query_log=1;

查询慢SQL日志状态及存储位置:

show variables like '%slow_query_log%';

设置慢查询阈值(默认为10s):

set global long_query_time =1;

除输出日志外还可以将慢查询输出的MySQL的系统表中的slow_log表:

SET GLOBAL log_output ='table,file';

以上在控制台全局的设置在数据库重启后就会失效,如果要长久生效,就要在配置文件进行修改。

2. 分析慢SQL

直接打开log日志

或者直接查找slow_log表:

利用EXPLAIN对慢SQL进行分析:

explain select * from order_detail where name like '%蛙';

主要关注type和key字段

type:表示查询时使用的访问方法或策略,常见值包括ALL、index、range等,一般着重优化ALL全表扫描。

key:表示查询时所使用的索引。

3.SQL优化(SQL语句优化和索引优化)

实例表

创建普通联合索引:

ALTER TABLE user ADD INDEX `idx_username_name_age` (`username`, `name`, `age`);

1. 索引全覆盖:是指在数据库查询过程中,所需的所有数据都可以从索引中直接获取,而无需访问表中的实际数据行。例如:

SELECT name, age FROM user WHERE username = 'Tom';

需要查询的name和age字段都可以直接从idx_username_name_age索引中直接获取。

2. 遵循最左前缀

SELECT * FROM user WHERE name = 'Qwen' AND username = 'laowang' AND age = 30 

A_B_C复合索引,如果查询条件是A_C,则只有A索引生效,如果是A_B,则A和B都生效,如果是B_C,则索引失效。

3. 索引列上少计算:

不在索引列上做任何操作(计算、函数、类型转换),会导致索引失效转向全表扫描。

例如: 

where Year(date) = 2025   where (Varchar)2 = (Integer)2

4. 范围之后全失效

还是A_B_C的复合索引,如果 where A = a AND B > b AND C = c,因为范围查找后后续字段无序,所以C索引失效。 

5. Like百分写最右

where name = '%xx',索引失效,where name='xx%',索引生效,因为百分写前面相当于要对全部数据查询在确定是否包含xx,百分写前面可以根据name索引确定xx开头的,所以可以使用索引。

6. 覆盖索引不写星

写星会导致查询时回表

7. 不等空值还有or会导致索引失效

如果语句中提示存在possible_key,可以进行优化,使用FORCE INDEX(索引名)

explain SELECT name, age FROM user FORCE INDEX (idx_username_name_age) WHERE username != 'Tom';

or导致失效是因为数据库不能支持直接合并不同索引,所以优化器选择全表扫描。

可以使用Union ALL代替(当name和username都有索引时)

explain select * from user where name='汤姆' or username='Rose';
explain (select * from user where name = '汤姆')union ALL(select * from user where username='Rose');

8 字符串不加单引号索引失效

explain select * from user where name='1000';
explain select * from user where name= 1000;

其实就是类型转化,需要对每一个name都转化为Integer,所以选择全表扫描。

SQL语句优化:

1. 避免使用select *

查询时需要将星号解析成表的所有字段然后再查询,增加解析器的成本

select * 查询一般不走覆盖索引会产生大量的回表查询

在实际应用中通常只需要使用某几个字段,其他不需要使用的字段也查询出来浪费CPU和内存资源

2. 小表驱动大表

3.当子查询是小表,查询是大表,可以用连接查询代替子查询使索引生效。

4. 为group by字段添加索引

5. 将循环插入改变为动态SQL批量插入(控制在500以内)

6. 利用limit进行分页查询,对于大数据量的表限制分页查询范围。因为offset越大,查询越慢

对于limit 10000 10,需要先查询1万条数据才得到后面10条数据。改进 :

where id>=10000 limit 10 # 直接定位到一万的位置

7. 在不要求去重的情况下使用Union all 替代Union

8. join的表不宜过多,一般控制在3个以下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值