sql优化方法

基础优化方法

1.使用索引,在创建索引时,需要考虑查询的频率和数据的更新频率,避免过度索引或不必要的索引。

2.尽量避免使用SELECT *,而是明确指定需要查询的字段。这样可以减少返回的数据量,提高查询效率。

优化查询条件

1.在查询数据时,尽量使用WHERE子句对数据进行过滤,减少返回的数据量。

2.使用索引覆盖查询

索引覆盖查询是指查询的字段都包含在索引中,不需要回表查询数据。这样可以减少IO操作,提高查询效率。

3.避免在WHERE子句中使用函数

在WHERE子句中使用函数会导致索引失效,需要全表扫描。

4.使用合适的数据类型

选择合适的数据类型可以减少存储空间和查询时间,提高数据库性能。

连接查询优化

1.使用INNER JOIN代替WHERE子句连接

-- 不推荐
SELECT * FROM table1, table2 WHERE table1.id = table2.id;
-- 推荐
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;

联表查询(也称为多表查询)在没有正确指定连接条件的情况下,确实会导致笛卡尔积(Cartesian product)的情况。笛卡尔积是两个集合中所有可能的有序对的集合,而在数据库查询中,它指的是两个或多个表中的每一行都与另一个表中的每一行组合。

当你使用SELECT * FROM table1, table2这样的语法时,你实际上是在告诉数据库你想看到table1和table2的笛卡尔积,除非你在WHERE子句中指定了连接条件来限制结果集。

例如,如果table1有3行,而table2有4行,那么没有连接条件的查询将返回12行结果(3乘以4)。

但是,当你使用INNER JOIN(或LEFT JOIN、RIGHT JOIN、FULL JOIN等)并指定了连接条件时,数据库只会返回满足该条件的行组合。

2.在连接查询时,尽量使用JOIN ON对连接进行过滤,而不是在WHERE子句中过滤连接。

-- 不推荐
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
 WHERE table2.name = 'value';

-- 推荐
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id 
AND table2.name = 'value';

3.根据实际业务需求选择合适的连接类型,包括INNER JOIN、LEFT JOIN、RIGHT JOIN和FULL JOIN。

子查询优化

1.使用EXISTS代替IN

在使用子查询时,尽量使用EXISTS代替IN,EXISTS只关心是否存在记录,而IN会将子查询的结果集加载到内存中,可能导致性能问题。

-- 不推荐
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);

-- 推荐
SELECT * FROM table1 WHERE EXISTS
 (SELECT 1 FROM table2 WHERE table1.id = table2.id);

IN和EXISTS的区别和使用

in()适合子表比主表数据小的情况

exists()适合子表比主表数据大的情况

当主表数据与子表数据一样大时,in与exists效率差不多,可任选一个使用

in的性能分析

select * from A
where id in(select id from B)

sql会先执行括号内的子查询,再执行主查询

0、当前的in子查询是B表驱动A表

1、mysql先将B表的数据一把查出来置于内存中

2、遍历B表的数据,再去查A表(每次遍历都是一次连接交互,这里会耗资源)

3、假设B有100000条记录,A有10条记录,会交互100000次数据库;再假设B有10条记录,A有100000记录,只会发生10次交互。

Exists的性能分析

select a.* from A a
where exists(select 1 from B b where a.id=b.id)

0、当前exists查询是A表驱动B表

1、与in不同,exists将A的纪录数查询到内存,因此A表的记录数决定了数据库的交互次数

2、假设A有10000条记录,B有10条记录,数据库交互次数为10000;假设A有10条,B有10000条,数据库交互次数为10。

2.使用JOIN代替子查询

在查询中使用JOIN可以更好地表达查询的逻辑,避免使用复杂的子查询。

-- 不推荐
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);

-- 推荐
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;

LIMIT优化

1.在查询大量数据时,使用LIMIT可以限制返回的记录数,避免查询过多的数据。

排序优化

1.通常应该选择已经建立了索引的字段进行排序,避免对大量数据进行排序操作。

2.如果查询中只需要排序字段,并且该字段已经建立了索引,可以使用覆盖索引来减少排序的时间。

避免使用通配符

1.在查询数据时,尽量避免使用%通配符在查询字段的开头,这会导致索引失效,需要进行全表扫描。

2.如果需要在查询中使用通配符%在字段的结尾,可以使用前缀索引来优化查询性能。

联合查询优化

1.使用UNION ALL代替UNION

在使用联合查询时,如果不需要去重操作,应该使用UNION ALL,可以减少查询的开销。

-- 不推荐
SELECT * FROM table1 WHERE condition
UNION
SELECT * FROM table2 WHERE condition;


-- 推荐
SELECT * FROM table1 WHERE condition
UNION ALL
SELECT * FROM table2 WHERE condition;

2.使用EXISTS代替IN和UNION

在查询中使用EXISTS代替IN和UNION,可以更好地表达查询逻辑,提高查询性能。

-- 不推荐
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2 WHERE condition)
UNION
SELECT * FROM table1 WHERE id IN (SELECT id FROM table3 WHERE condition);


-- 推荐
SELECT * FROM table1 WHERE EXISTS
 (SELECT 1 FROM table2 WHERE table1.id = table2.id AND condition)
OR EXISTS (SELECT 1 FROM table3 WHERE table1.id = table3.id AND condition);

数据表设计优化

1.使用合适的数据类型

在创建数据表时,选择合适的数据类型可以减少存储空间和查询时间,提高数据库性能。

-- 不推荐
CREATE TABLE table_name (id VARCHAR(100), name VARCHAR(100));

-- 推荐
CREATE TABLE table_name (id INT, name VARCHAR(100));

2.垂直拆分表

在数据表中包含大量冗余数据时,可以考虑对表进行垂直拆分,将不同的数据拆分到不同的表中,提高查询性能。

相关推荐
叫我萧风啊9 分钟前
25.labview数据采集中的读取和写入文本文件和Excel表格文件
数据库·计算机视觉·自动化·excel·labview
u01040583634 分钟前
SQLMap工具详解与SQL注入防范
数据库·sql
喜欢猪猪35 分钟前
MySQL 聚集索引与非聚集索引的概念以及优缺点
数据库·mysql
TPBoreas2 小时前
物理删除和逻辑删除区别
数据库·oracle
InterestingFigure2 小时前
头条系统-05-延迟队列精准发布文章-概述&添加任务(db和redis实现延迟任务)、取消&拉取任务&定时刷新(redis管道、分布式锁setNx)...
数据库·redis·分布式·缓存
前端组件开发2 小时前
JeeSite V5.7.1 发布,Java快速开发平台,Spring Boot,Vue3,微服务
java·数据库·spring boot·微服务·oracle·开源
BinTools图尔兹2 小时前
CQ 社区版2.13.3 | 支持全局开启OTP登录、文本导入功能可独立控制……
数据库·安全·dba·数据库管理员
henan程序媛2 小时前
MySQL备份与恢复
数据库·mysql·备份与恢复
Zonda要好好学习2 小时前
黑马点评DAY1|Redis入门、Redis安装
数据库·redis·oracle
danielli3 小时前
如何设计通用用户、权限、菜单数据表
数据库·oracle