问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

SQL语句优化【超详解】

创作时间:
作者:
@小白创作中心

SQL语句优化【超详解】

引用
CSDN
1.
https://m.blog.csdn.net/weixin_62754939/article/details/144083097

在数据库开发和运维工作中,SQL语句的优化是一项至关重要的技能。本文将从多个维度深入探讨SQL优化的重要性,并通过具体案例展示优化策略的实际应用效果。

一、SQL优化的重要性

  • 性能提升:优化后的 SQL 查询可以显著减少查询执行时间。在处理大型数据集或高并发的数据库应用中,高效的 SQL查询能够快速响应请求,提高系统的整体性能。例如,一个未优化的复杂查询在处理百万级数据量时可能需要数秒甚至数分钟才能返回结果,而经过优化后可能在毫秒级时间内就能完成。

  • 资源利用效率:减少数据库服务器的资源消耗,包括 CPU、内存和磁盘 I/O。优化的 SQL语句可以避免不必要的计算和数据读取,从而降低服务器的负载,使服务器能够更高效地处理更多的请求。这对于资源有限的数据中心或者云数据库环境尤为重要。

  • 用户体验改善:快速的查询响应可以直接提升用户体验。无论是在网页应用、移动应用还是其他软件系统中,用户都期望能够快速获取所需的数据。例如,在电商网站中,快速的商品搜索和详情查询可以提高用户的购物满意度。

二、SQL优化策略

(1)只查询一条语句的时候,使用limit 1

当只需要一条数据时,使用LIMIT 1可以让数据库在找到符合条件的第一条记录后就停止查询,而不是继续搜索整个结果集。这在处理大型数据表时尤为重要,因为它能够显著减少从数据库服务器传输到应用程序的数据量。例如,在一个包含数百万条销售记录的数据库中,如果只需要查询最近一笔销售的日期,使用LIMIT 1可以避免传输大量不必要的记录,节省网络带宽并提高查询响应速度。


SELECT id,name FROM products WHERE id=20241111;  

优化:


SELECT id,name FROM products WHERE id=20241111 limit 1;  

比如我们在通过学生的学号去查询时,如果我们是查询一条数据,在数据量大的时候,第二条sql性能明显优于第一条

(2)避免在where子句中对字段进行表达式操作

在 SQL 的WHERE子句中对字段进行表达式操作可能会导致数据库无法有效使用索引。当在WHERE子句中直接使用字段的值进行比较(如WHERE column_name = ‘value’)时,如果该字段上有索引,数据库可以利用索引快速找到符合条件的数据。然而,当对字段进行表达式操作时,数据库可能无法识别索引或者不能有效地利用索引来优化查询。

我们如果对字段进行了操作,这样会导致索引失效,如下:


SELECT id,name FROM products WHERE price + 10 > 110;  

优化:


SELECT id,name FROM products WHERE price > (110 - 10);  

(3)SELECT语句务必指明字段名称

查找哪个字段,就写具体的字段,数据库在处理查询请求时,对于明确指定字段的查询,能够更精准地定位和获取所需数据,无需对不必要的字段进行处理和读取操作。这有助于减少数据库内部的资源消耗,如 CPU 时间和内存的占用,从而使查询能够更快速地执行完成,提高整体的查询效率


SELECT * FROM products WHERE price  > 100;  

优化:


SELECT id,name FROM products WHERE price  > 100;  

(4)count 优化

速度:count(*)>count(1)>count(字段)

  • count( * ):inndb引擎,特意做了优化,不会取出值,直接服务层进行累加 (建议使用)

  • count(字段):遍历整张表会把每一行的字段值取出来,然后返回

  • count( 1 ): 便利整张表,但不取值,对于返回的数据,放入1进去.然后累加

(5)不建议使用%前缀模糊查询

Llike “%name”或者 like “%name%”,这种查询会导致索引失效而进行全表扫描。但是可以使用LIKE “name%”。


 explain select * from  `user_test` where uid=10 and  uid like  "%1" ;  
explain select * from  `user_test` where uid=10 and  uid like  "1%" ;  

(6)字符串类型的字段 查询的时候如果不加引号’’ ,会导致自动进行隐式转换,然后索引失效


SELECT * FROM users WHERE username = 123;  

这里没有给 123 加上引号,数据库会尝试将username列中的每个值转换为数字类型。假设username列中的值都是字符串,这种转换可能会导致索引无法正常使用。

优化:


SELECT * FROM users WHERE username = '123';  

三、优化案例*

案例一:电商订单查询优化

场景描述:

在一个电商系统中,有一个包含大量订单记录(数百万条)的orders表,需要查询某个特定用户的最后一笔订单的详细信息,用于展示用户的最新订单状态。

原始查询:


SELECT * FROM orders  
WHERE user_id = 12345  
ORDER BY order_date DESC;  

问题分析:

没有限制返回结果的数量,数据库需要对满足user_id = 12345的所有订单进行排序,然后返回所有记录。当符合条件的订单数量较多时,会传输大量不必要的数据,并且排序操作也会消耗较多资源。

优化后的查询:


SELECT * FROM orders  
WHERE user_id = 12345  
ORDER BY order_date DESC  
LIMIT 1;  

优化效果:

数据库在找到符合用户 ID 且日期最新的第一条订单记录后就停止查询,大大减少了数据传输量和排序操作的范围。在实际测试中,原始查询可能需要数秒才能返回结果,优化后的查询在毫秒级就能完成,显著提高了查询性能。

案例二:论坛帖子搜索优化

场景描述:

一个论坛系统有一个posts表,用于存储帖子信息,其中title列存储帖子标题,并且在title列上有索引。用户经常使用标题关键词进行搜索,例如搜索标题包含 “SQL 优化技巧” 的帖子。

原始查询:


SELECT * FROM posts  
WHERE title LIKE '%SQL优化技巧%';  

问题分析:

这种以%开头的模糊查询会导致索引失效,数据库不得不进行全表扫描来查找符合条件的帖子。当帖子数量庞大时,查询速度会变得非常慢。

优化后的查询:

可以添加一个额外的全文索引(如果数据库支持),例如在 MySQL 中使用FULLTEXT索引。

首先创建全文索引:


ALTER TABLE posts ADD FULLTEXT (title);  

然后使用全文搜索查询:


SELECT * FROM posts  
WHERE MATCH(title) AGAINST ('SQL优化技巧');  

优化效果:

对于包含大量文本数据的posts表,使用全文索引后的查询速度相比之前的模糊查询有了显著提升。全文索引能够利用特定的搜索算法,快速定位包含关键词的记录,避免了全表扫描,大大提高了查询效率。

案例三:员工工资统计优化

场景描述:

在公司的人力资源管理系统中,有一个employees表,包含employee_id、department_id、salary等列。需要统计每个部门的员工工资总和。

原始查询:


SELECT department_id, SUM(salary)  
FROM employees  
GROUP BY department_id;  

问题分析:

假设employees表数据量较大,且有频繁的插入、更新操作。如果在salary列上有索引,频繁的求和操作可能会影响索引的性能。因为每次计算总和时,数据库可能需要读取索引中的每个值,增加了额外的开销。

优化后的查询(如果允许适当的数据冗余):

可以创建一个新的表department_salary_summary,用于存储每个部门的工资总和,并且在员工工资发生变化时(如插入新员工、更新员工工资),通过触发器或者定时任务来更新这个汇总表。

创建汇总表的查询:


CREATE TABLE department_salary_summary (  
    department_id INT PRIMARY KEY,  
    total_salary DECIMAL(10,2)  
);  

插入初始汇总数据:


INSERT INTO department_salary_summary (department_id, total_salary)  
SELECT department_id, SUM(salary)  
FROM employees  
GROUP BY department_id;  

查询汇总数据:


SELECT * FROM department_salary_summary;  

优化效果:

当需要频繁查询部门工资总和时,直接从汇总表中获取数据,避免了对原始employees表进行重复的分组求和操作,大大提高了查询速度。同时,虽然增加了一定的数据维护成本(通过触发器或定时任务更新汇总表),但在查询性能上的提升在很多情况下是值得的。

四、结语

SQL 优化是数据库管理与应用开发中不可或缺的关键环节。通过深入理解其重要性,熟练掌握如合理使用LIMIT 1、避免WHERE子句字段表达式操作、精准指定SELECT字段、优化count函数使用、谨慎对待模糊查询以及正确处理字符串引号等一系列优化策略,并结合实际的优化案例进行实践应用,能够让数据库系统在面对大规模数据和高并发请求时展现出卓越的性能表现。无论是电商平台的订单处理、论坛的信息检索,还是企业内部的人力资源数据统计,都能从中受益,实现资源的高效利用,为用户提供更为流畅、快捷的体验,在当今数据驱动的时代背景下,助力企业和开发者在激烈的竞争中脱颖而出,构建出高效、稳定且用户友好的数据库应用体系,为数据的存储、管理与应用挖掘出更大的价值与潜力。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号