mysql性能优化-SQL 查询优化

MySQL 性能优化之 SQL 查询优化

MySQL 是常用的开源关系型数据库管理系统(RDBMS),具有高效、稳定、易用等特点。在大数据量和高并发的场景中,数据库性能的瓶颈往往是 SQL 查询不够高效。因此,SQL 查询优化是 MySQL 性能优化的重要环节之一。


1. SQL 查询优化的必要性

在数据库应用中,SQL 查询的效率直接影响应用程序的性能。随着数据量的增加,查询响应时间也会变得更长。如果没有良好的查询优化策略,复杂查询可能会消耗大量的系统资源,导致数据库性能下降,影响系统的吞吐量和用户体验。

通过优化 SQL 查询,能有效减少查询时间,降低数据库服务器的负载,提高并发处理能力。


2. 索引优化

2.1 索引的作用

索引是优化 SQL 查询最有效的方法之一。它类似于书的目录,帮助数据库快速定位所需数据,减少全表扫描的开销。

2.2 使用合适的索引
  1. 单列索引:为查询条件中的某个列创建索引。例如:

    CREATE INDEX idx_username ON users(username);
    

    当查询涉及 username 字段时,索引将加快查找速度:

    SELECT * FROM users WHERE username = 'john_doe';
    
  2. 复合索引(多列索引):如果查询涉及多个条件,可以创建复合索引。复合索引包含多个字段,MySQL 会按索引字段的顺序匹配。

    CREATE INDEX idx_username_email ON users(username, email);
    

    这条索引在查询时不仅加速了单个字段查询(如 username),也可以加速组合条件查询:

    SELECT * FROM users WHERE username = 'john_doe' AND email = 'john@example.com';
    
2.3 索引的最佳实践
  • 选择性高的字段上创建索引:索引最适合用于选择性较高的字段(唯一值较多的字段),如用户 ID 或邮箱。
  • 避免过多的索引:虽然索引可以加速查询,但创建过多的索引也会增加数据库的写操作成本(如 INSERTUPDATEDELETE),因为每次修改数据都需要更新索引。
  • 复合索引的顺序:在复合索引中,最左边的字段应该是选择性最高的字段,因为 MySQL 在匹配索引时会按照从左到右的顺序进行匹配。
2.4 覆盖索引

覆盖索引是指查询中所需要的字段都可以从索引中获取,而不需要访问实际的表数据。这样可以显著提高查询效率。

SELECT username, email FROM users WHERE username = 'john_doe';

如果 usernameemail 都在索引中,这个查询就可以只从索引中获取数据,而不需要查询实际的数据表,减少 I/O 操作。


3. 查询语句优化

3.1 避免使用 SELECT *

使用 SELECT * 会查询出表中的所有列,但往往并不是所有的列都需要返回。查询不必要的列会增加网络传输和数据库处理的开销。因此,应该明确指定需要的列:

SELECT username, email FROM users WHERE id = 1;
3.2 减少 JOIN 的使用

JOIN 操作会将多个表的数据进行合并,通常会带来较大的性能开销。尤其是在大数据量表上进行多表 JOIN 时,会导致查询速度变慢。因此,尽量避免复杂的 JOIN,并确保连接条件上有适当的索引。

如果确实需要 JOIN 操作,可以考虑拆分查询,分步骤执行,或进行表的反范式化设计(即适当冗余数据)。

3.3 使用合适的 WHERE 条件

优化查询最直接的方法是使用合适的 WHERE 条件,避免全表扫描。WHERE 条件应与索引字段相结合,以加快检索速度。

例如,避免对索引列进行函数或操作:

-- 避免这种写法,因为它会导致索引失效
SELECT * FROM users WHERE YEAR(created_at) = 2023;-- 推荐的做法是直接使用索引字段的比较
SELECT * FROM users WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';
3.4 使用 EXPLAIN 分析查询

MySQL 提供了 EXPLAIN 命令来帮助分析 SQL 查询的执行计划。通过 EXPLAIN,可以了解查询是否使用了索引、查询的执行顺序等信息。

EXPLAIN SELECT * FROM users WHERE username = 'john_doe';

EXPLAIN 的输出中,重点关注以下字段:

  • type:表示查询的类型。ALL 表示全表扫描,index 表示使用了索引,refeq_ref 表示有效的索引匹配。
  • key:表示查询使用的索引。
  • rows:表示预计扫描的行数,行数越少越好。

根据 EXPLAIN 结果,可以针对性地优化查询和索引。

3.5 避免 OR 条件中的索引失效

OR 条件中的索引使用需要特别注意,某些情况下可能导致索引失效。

-- 如果 username 和 email 都没有联合索引,查询会导致全表扫描
SELECT * FROM users WHERE username = 'john_doe' OR email = 'john@example.com';

可以改为使用 UNION 将两次查询合并:

SELECT * FROM users WHERE username = 'john_doe'
UNION
SELECT * FROM users WHERE email = 'john@example.com';

这样能更好地利用索引,提高查询性能。


4. 表结构优化

4.1 规范化与反规范化

数据库设计中有两种设计范式:规范化反规范化。规范化通过减少数据冗余来提高数据一致性,而反规范化则通过适度的数据冗余来提高查询性能。在性能要求较高的场景下,可以考虑反规范化,以减少 JOIN 查询。

4.2 合理选择数据类型

为表中的字段选择合适的数据类型可以显著提高查询效率。例如:

  • 使用 INT 类型来存储数值型数据,而不是 VARCHAR
  • 对于定长字符,可以使用 CHAR 而不是 VARCHAR,提高存储和查询效率。
  • 使用 DECIMAL 类型来存储货币等精确数值,而不是 FLOATDOUBLE,以避免精度问题。
4.3 拆分大表

当表的数据量非常大时,可以考虑将表按时间或其他条件进行垂直或水平拆分。水平拆分是将数据按行进行分表,垂直拆分是将表的列进行拆分。

例如,按日期进行分表:

CREATE TABLE users_2023 LIKE users;
INSERT INTO users_2023 SELECT * FROM users WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';

通过分表,可以减少单个表的数据量,从而提高查询性能。


5. 缓存查询结果

5.1 MySQL 查询缓存

MySQL 提供了查询缓存功能,可以缓存查询结果,减少相同查询的执行次数。不过,MySQL 8.0 版本已经弃用了查询缓存功能,建议使用应用层的缓存系统(如 Redis)来缓存频繁查询的结果。

5.2 使用 Redis 进行缓存

通过将一些热点数据存储在 Redis 中,可以减少对 MySQL 的访问次数,从而显著提高查询性能。

# 使用 Redis 缓存查询结果(示例为 Python)
import redisr = redis.Redis(host='localhost', port=6379, db=0)# 首先检查缓存中是否有数据
cached_data = r.get('user_1')
if cached_data:# 如果缓存命中,返回缓存中的数据return cached_data
else:# 如果缓存未命中,查询 MySQLdata = query_mysql_for_user(1)# 将查询结果写入缓存r.set('user_1', data)return data

通过缓存可以大幅减少对数据库的查询压力,提升应用性能。


6. 总结

MySQL 查询优化是数据库性能优化的重要环节

。通过合理使用索引、优化查询语句和设计表结构,可以显著提高 MySQL 的查询性能。

  • 索引优化:为高频查询字段创建合适的索引,并避免过多的索引。
  • 查询语句优化:避免使用 SELECT *,简化 JOIN 操作,优化 WHERE 条件。
  • 表结构优化:合理规范化与反规范化,选择合适的数据类型,必要时进行表拆分。
  • 缓存优化:使用 Redis 等缓存系统来减轻数据库查询压力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1541983.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

极度精简 Winows11 系统镜像!Tiny11 2311下载 - 支持苹果 M 芯片 Mac 安装 (ARM 精简版)!

最新推出的 Tiny11 是一款极端精简版 Windows 11 系统镜像,针对苹果 M 芯片 Mac 用户(ARM 架构)提供良好支持。Tiny11 内置了众多优化特性,如更小的安装体积和更快的启动速度,特别适合有特殊需求或老机型的用户。用户可…

华为HarmonyOS地图服务 7- 在地图上绘制标记

场景介绍 本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。 点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、…

基于YOLO算法的网球运动实时分析-击球速度测量-击球次数(附源码)

这个项目通过分析视频中的网球运动员来测量他们的速度、击球速度以及击球次数。该项目使用YOLO(You Only Look Once)算法来检测球员和网球,并利用卷积神经网络(CNNs)来提取球场的关键点。此实战项目非常适合提升您的机…

VsCode C语言 SDL包配置 2024.9

写这篇文章的起因是,最近我需要使用 SDL 包,我懒得下载V-studio ,所以直接在VsCode 里配置C环境。我搞了好几个小时,啥都弄好了,但是一直被下面几个问题缠绕导致demo启动不了,现在我记录一下这奇葩的解决过程。所有路径…

Qt Debugging帮助文档

Qt中给断点添加条件: 示例1: 当i10时,程序中断 但不知道为什么,46行的条件没有生效,47行的条件生效了 给断点添加忽略次数: 在程序停止之前忽略该断点200次。 Breakpoints (Debugging with GDB)

Apache Doris 实践

Apache Doris 实践 官方使用指南:https://doris.incubator.apache.org/zh-CN/docs/install/source-install/compilation-with-docker/ 手动安装 下载二进制安装包https://apache-doris-releases.oss-accelerate.aliyuncs.com/apache-doris-2.1.5-bin-x64.tar.gz …

华润电力最新校招社招润择认知能力测评:逻辑推理数字计算语言理解高分攻略

​ 尊敬的求职者们, 在您准备加入华润电力这个大家庭之前,了解其招聘测评的详细流程和要求是至关重要的。以下是我们为您整理的测评系统核心内容,希望对您的求职之旅有所帮助。 测评系统概览 华润电力的招聘测评系统旨在全面评估求职者的认…

机器学习04-逻辑回归(python)-02原理与损失函数

1. 逻辑回归概念 逻辑回归(Logistic Regression) 是一种 分类模型,主要用于解决 二分类问题(即分成两类,如是否通过、是否患病等)。逻辑回归的目标是根据输入的特征预测一个 概率,这个概率值介于…

计算机毕业设计hadoop+spark+hive新能源汽车销售数据分析系统 二手车销量分析 新能源汽车推荐系统 可视化大屏 汽车爬虫 机器学习

《HadoopSparkHive新能源汽车销售数据分析系统》开题报告 一、选题背景与意义 1.1 选题背景 随着全球对环境保护意识的增强和能源结构的转型,新能源汽车市场迅速崛起。新能源汽车的销售数据不仅反映了市场趋势和消费者偏好,还为企业决策、政府监管和政…

微服务——网关登录校验(一)

1.网关登录校验 微服务中的网关登录校验是微服务架构中常见的一种安全机制,用于在请求到达微服务之前,对用户的身份进行验证,确保只有合法的用户才能访问相应的服务。 在微服务架构中,每个微服务都是独立部署的,它们之…

(C++17) optional 的 3 种用法

文章目录 *️⃣前言*️⃣3 种主流用法1️⃣函数返回值2️⃣函数参数3️⃣类成员 ⭐END🌟跋🌟交流方式 *️⃣前言 在 C17 中标准化了 std::optional。该类型可以容纳一种类型,且判断是否有无。 若使用的标准在低于 C17 则可以使用 Abseil 的…

浅谈递推法

递推法 递推法是一种数学方法,用于通过利用已知的初始条件和递推关系来计算要求中的每一项。以数列来举例,在递推法中,它的思想很简单:我们首先知道数列的第一项(初始条件),然后通过一个规律&a…

GEE 数据集:人类造成的热带潮湿森林退化程度的估计

目录 简介 摘要 代码 结论 数据和代码 引用 网址推荐 0代码在线构建地图应用 机器学习 人类造成的热带潮湿森林退化程度超出了先前的估计 简介 选择性采伐、火灾和边缘效应造成的热带森林退化是碳和生物多样性损失的主要驱动因素1,2,3,其年增长率可与森林砍伐相媲美…

Golang | Leetcode Golang题解之第424题替换后的最长重复字符

题目: 题解: func characterReplacement(s string, k int) int {cnt : [26]int{}maxCnt, left : 0, 0for right, ch : range s {cnt[ch-A]maxCnt max(maxCnt, cnt[ch-A])if right-left1-maxCnt > k {cnt[s[left]-A]--left}}return len(s) - left }f…

【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物,那么便到不了终点“

【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物,那么便到不了终点“ 1.题目 下方是力扣官方题目的地址 63. 不同路径 II 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下…

【全网最全】2024年华为杯研赛A题成品论文获取入口(后续会更新)

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片,那是获取资料的入口! 点击链接加入【2024华为杯研赛资料汇总】:https://qm.qq.com/q/hMgWngXvcQhttps://qm.qq.com/q/hMgWngXvcQ你是否在寻找数学建模比赛的突破点&am…

BUUCTF逆向wp [WUSTCTF2020]Cr0ssfun

第一步 查壳,本题是64位,无壳。 第二步 查看主函数,点开看主函数,没什么东西。 左边表里面看到好几个i开头的函数(红色方框里面),点开看后每个函数的最后末尾(图中红色椭圆圈那里&a…

(笔记自用)位运算总结+LeetCode例题:颠倒二进制位+位1的个数

一.位运算总结: 在解题之前理解一下为什么需要位运算?它的本质是什么? 力扣上不少位运算相关的题,并且很多题也会用到位运算的技巧。这又是为什么? 位运算的由来 在计算机里面,任何数据最终都是用数字来表示的&…

在Java中基于GeoTools的Shapefile读取乱码的问题解决办法

目录 前言 1、Shapefile属性字段编码的情况: 一、Shp文件常见的字符集编码 1、System编码 2、ISO-8859-1编码 3、UTF-8编码 二、GeoTools解析实战 1、未进行字符处理 2、乱码问题的解决 3、转码支持 4、属性字段编码结果 三、总结 前言 文件编码&#x…

分布式锁优化之 使用lua脚本改造分布式锁保证判断和删除的原子性(优化之LUA脚本保证删除的原子性)

文章目录 1、lua脚本入门1.1、变量:弱类型1.2、流程控制1.3、在lua中执行redis指令1.4、实战:先判断是否自己的锁,如果是才能删除 2、AlbumInfoApiController --》testLock()3、AlbumInfoServiceImpl --》testLock() 1、lua脚本入门 Lua 教程…