SQL 优化笔记:提高查询速度

SQL 优化笔记:提高查询速度

SQL 优化是提升数据库性能的关键环节。以下是一些常见的 SQL 优化策略,包含每种方法的原因和建议,可以帮助提高查询速度和整体性能。

1. 使用索引

1.1 创建索引

原因 :索引可以大大加快数据检索速度,通过创建索引,数据库可以更快地定位到所需数据,而无需扫描整个表。 建议:为查询中经常作为WHERE条件、JOIN条件或ORDER BY的列创建索引。

  • 单列索引:适用于经常作为查询条件的单列。

    复制代码
    sqlCopy CodeCREATE INDEX idx_column_name ON table_name(column_name);
  • 联合索引:适用于多个列一起作为查询条件的情况。

    复制代码
    sqlCopy CodeCREATE INDEX idx_column1_column2 ON table_name(column1, column2);
  • 注意:索引会增加写入操作的开销,避免为每个查询创建过多索引。

1.2 索引选择

原因 :选择性高的列(即唯一值多)能有效提高索引效率。 建议

  • 优先索引选择性高的列,如主键或唯一约束列。
  • 避免过多索引:每增加一个索引都会带来额外的维护开销,特别是对于写操作(插入、更新、删除)。

2. 优化查询语句

2.1 使用合适的查询条件

原因 :不必要的 SELECT * 或函数在 WHERE 子句中会导致全表扫描或失去索引效率。 建议

  • 选择需要的列:只查询实际需要的字段。

    复制代码
    sqlCopy CodeSELECT column1, column2 FROM table_name WHERE condition;
  • 避免在 WHERE 子句中使用不必要的函数:函数调用可能会导致索引失效。

    复制代码
    sqlCopy Code-- 不推荐
    SELECT * FROM table_name WHERE YEAR(date_column) = 2023;
    
    -- 推荐
    SELECT * FROM table_name WHERE date_column BETWEEN '2023-01-01' AND '2023-12-31';

2.2 使用 JOIN 而非子查询

原因JOIN 通常比子查询性能更优,尤其是在处理大数据集时。 建议

  • 使用 JOIN 替代子查询:在可能的情况下,尽量使用连接查询而非嵌套查询。

    sql 复制代码
    sqlCopy Code-- 子查询
    SELECT * FROM orders WHERE customer_id IN (SELECT customer_id FROM customers WHERE status = 'active');
    
    -- JOIN 查询
    SELECT orders.* FROM orders JOIN customers ON orders.customer_id = customers.customer_id WHERE customers.status = 'active';

2.3 小表驱动大表

原因 :小表驱动大表,也就是说用小表的数据集驱动大表的数据集。

假如有order和user两张表,其中order表有10000条数据,而user表有100条数据。

这时如果想查一下,所有有效的用户下过的订单列表。

可以使用in关键字实现:

sql 复制代码
select * from order
where user_id in (select id from user where status=1)

也可以使用exists关键字实现:

sql 复制代码
select * from order
where exists (select 1 from user where order.user_id = user.id and status=1)

前面提到的这种业务场景,使用in关键字去实现业务需求,更加合适。

为什么呢?

因为如果sql语句中包含了in关键字,则它会优先执行in里面的子查询语句,然后再执行in外面的语句。如果in里面的数据量很少,作为条件查询速度更快。

而如果sql语句中包含了exists关键字,它优先执行exists左边的语句(即主查询语句)。然后把它作为条件,去跟右边的语句匹配。如果匹配上,则可以查询出数据。如果匹配不上,数据就被过滤掉了。

这个需求中,order表有10000条数据,而user表有100条数据。order表是大表,user表是小表。如果order表在左边,则用in关键字性能更好。

总结一下:
in 适用于左边大表,右边小表。
exists 适用于左边小表,右边大表。
不管是用in,还是exists关键字,其核心思想都是用小表驱动大表。

2.4 优化分页查询

**原因:**当使用LIMIT和OFFSET进行分页时,随着页码的增加,查询性能会逐渐下降,因为数据库需要扫描越来越多的行来找到所需的起始点。

**建议:**使用基于索引的查询来优化分页,特别是当表很大时。例如,可以记录上一页最后一条记录的某个唯一标识符(如ID),并使用它作为下一页查询的起点。

例子:

优化前(随着页码增加性能下降)

复制代码
SELECT * FROM user LIMIT 10 OFFSET 100;

优化后(使用上一页的最后一条记录的ID)

复制代码
SELECT * FROM user WHERE id > LAST_SEEN_ID ORDER BY id LIMIT 10
相关推荐
2303_Alpha40 分钟前
深度学习入门:深度学习(完结)
人工智能·笔记·python·深度学习·神经网络·机器学习
Musennn43 分钟前
MySQL刷题相关简单语法集合
数据库·mysql
姝孟1 小时前
学习笔记(C++篇)—— Day 6
笔记·学习
Think Spatial 空间思维2 小时前
【HTTPS基础概念与原理】TLS握手过程详解
数据库·网络协议·https
霸王蟹2 小时前
React Fiber 架构深度解析:时间切片与性能优化的核心引擎
前端·笔记·react.js·性能优化·架构·前端框架
laowangpython2 小时前
MySQL基础面试通关秘籍(附高频考点解析)
数据库·mysql·其他·面试
~巴哥~2 小时前
mcp学习笔记
笔记·学习
mooyuan天天2 小时前
SQL注入报错“Illegal mix of collations for operation ‘UNION‘”解决办法
数据库·web安全·sql注入·dvwa靶场·sql报错
Johny_Zhao2 小时前
Vmware workstation安装部署微软SCCM服务系统
网络·人工智能·python·sql·网络安全·信息安全·微软·云计算·shell·系统运维·sccm
运维-大白同学2 小时前
go-数据库基本操作
开发语言·数据库·golang