sql优化
sql优化
在项目中的应用
- 有没有排查过慢sql的问题
- 如何定位慢sql
定义慢sql
- 执行比较慢的sql
如何筛选出执行时间超过1s的慢sql
- mysql本身 慢sql日志
- 数据库连接池
- 我们自己实现
- aop记录时间(4月30日作业)
能筛选慢sql,如何解决
首先要分析原因
资源不足
线程太多
查看负载
top
如何查看某个进程的负载?⭐
内存不足
- top
硬盘使用情况
- df -h
数据量太大
- 插入数据量比较大
- 批量插入-》500条开始-》批量条数
- 查询量
- 分库分表
- 限定查询条件
- 读写分离
- 查询频次
- 更新频次非常高
网络不好
- netstat
如何确定资源不足
怎么解决
错误使用
- 不当使用sql
- 索引失效
- 表设计不当
- 查询条件太多
- 死锁
- 锁竞争过多
explain
引起索引失效的一些语句
```
-- 索引失效的例子:函数操作列
SELECT * FROM table_name WHERE YEAR(date_column) = 2020;
未使用索引的列:如果查询中涉及的列没有被索引,可能会导致索引失效。
```
``` sql
-- 索引失效的例子:未使用索引的列
SELECT * FROM table_name WHERE non_indexed_column = 'value';
使用 OR 连接条件:OR 连接的条件可能会导致索引失效。
```
```sql
-- 索引失效的例子:OR 连接条件
SELECT * FROM table_name WHERE column1 = 'value1' OR column2 = 'value2';
使用不匹配索引的 LIKE 操作符:以通配符开头的 LIKE 子句可能会导致索引失效。
```
```sql
-- 索引失效的例子:以通配符开头的 LIKE 子句
SELECT * FROM table_name WHERE column_name LIKE '%value';
对索引列进行数学运算:对索引列进行数学运算可能会导致索引失效。
```
```sql
-- 索引失效的例子:数学运算
SELECT * FROM table_name WHERE indexed_column + 10 = 20;
使用不等于操作符(!= 或 <>):不等于操作符可能会导致索引失效。
```
```sql
-- 索引失效的例子:不等于操作符
SELECT * FROM table_name WHERE indexed_column != 'value';
排序操作:对索引列进行排序操作可能会导致索引失效。
```
```sql
-- 索引失效的例子:排序操作
SELECT * FROM table_name ORDER BY indexed_column;
JOIN 操作:JOIN 操作中未使用索引的列可能会导致索引失效。
```
```sql
-- 索引失效的例子:JOIN 操作
SELECT * FROM table1 JOIN table2 ON table1.indexed_column = table2.non_indexed_column;
```
使用函数或计算:在索引列上使用函数或进行数学运算(如SUBSTR, DECODE, INSTR,或除法、乘法等),或在查询中对索引列使用函数,都会导致索引失效。因为索引存储的是原始数据值,而非经过计算或函数处理后的值。
例如:
sql
SELECT * FROM table WHERE SUBSTR(indexed_column, 1, 5) = 'value';
LIKE查询条件不匹配:当使用LIKE关键字进行模糊查询时,如果通配符%放在查询字符串的开始位置,索引通常不会被使用。
例如:
sql
SELECT * FROM table WHERE indexed_column LIKE '%value';
联合索引未按最左前缀原则使用:对于多列联合索引,查询条件必须包含索引的最左侧列,否则索引可能不会被使用。
例如,对于索引(a, b, c):
sql
SELECT * FROM table WHERE b = 'value'; -- 索引失效,因为未使用最左侧的a列
使用OR关键字:当查询条件中使用OR关键字连接多个条件时,如果OR前后的列不都是索引列,那么索引可能不会被使用。
例如:
sql
SELECT * FROM table WHERE column1 = 'value1' OR column2 = 'value2'; -- 如果column1和column2不都是索引列,索引可能失效
数据类型不匹配:当查询条件中的数据类型与索引列的数据类型不匹配时,可能会导致索引失效。例如,字符型字段在WHERE条件中未加引号。
使用不等于操作符:在查询条件中使用<>、NOT IN、NOT EXIST等操作符时,如果结果集很大,数据库优化器可能会选择不使用索引,而是进行全表扫描。
单独引用复合索引的非首列:对于复合索引,如果查询条件只引用了非首列的索引列,那么索引可能不会被使用。
例如,对于索引(a, b):
sql
SELECT * FROM table WHERE b = 'value'; -- 如果未使用a列,索引可能失效
索引列包含大量重复数据:当索引列包含大量重复数据时,即使建立了索引,查询优化器也可能选择不使用索引,因为全表扫描可能更加高效。
查询优化器的选择:查询优化器会根据统计信息和查询成本来决定是否使用索引。有时,即使存在索引,优化器也可能认为全表扫描更快,从而选择不使用索引。
