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.垂直拆分表

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

相关推荐
csdn_aspnet7 分钟前
用 MySQL 玩转数据可视化:从底层数据到 BI 工具的桥接
数据库·mysql·信息可视化·bi
wb0430720113 分钟前
一次jvm配置问题导致的数据库连接异常
服务器·jvm·数据库·后端
酷酷的崽79813 分钟前
搭载cpolar,让PostgreSQL数据库远程访问超丝滑
数据库·postgresql
API开发20 分钟前
apiSQL 迁移至已有 PostgreSQL 数据库指南
数据库·postgresql·api开发·postgrest·接口开发工具·api管理软件
学掌门23 分钟前
从数据库到可视化性能,5个大数据分析工具测评,python只排倒数
数据库·python·数据分析
编程小风筝24 分钟前
Django REST framework实现安全鉴权机制
数据库·安全·django
secondyoung24 分钟前
队列原理与实现全解析
c语言·数据库·mysql·算法·队列
Hello.Reader26 分钟前
Flink DataGen SQL Connector 本地造数、压测、边界数据与“像真数据”的生成技巧
大数据·sql·flink
05大叔30 分钟前
微服务Day01 MP
数据库·oracle
Jan123.33 分钟前
深入理解数据库事务与锁机制:InnoDB实战指南
数据库·学习