MySQL数据库——常见慢查询优化方式

本文详细介绍MySQL的慢查询相关概念,分析步骤及其优化方案等。

在这里插入图片描述

文章目录

      • 什么是慢查询日志?
      • 慢查询日志的相关参数
      • 如何启用慢查询日志?
        • 方式一:修改配置文件
        • 方式二:通过命令动态启用
      • 分析慢查询日志
        • 方式一:直接查看日志文件
        • 方式二:使用`EXPLAIN`分析查询
      • 常见的慢查询优化
        • 1. 数据类型优化
        • 2. 索引优化
        • 3. SQL 查询优化
        • 4. 分库分表
      • 慢查询日志的适用场景
      • 慢查询日志的优缺点
      • 总结

什么是慢查询日志?

慢查询日志是MySQL提供的一种日志记录机制,用于记录执行时间超过指定阈值(long_query_time)的SQL语句。通过慢查询日志,可以识别和优化性能较差的SQL查询,是数据库性能调优的重要工具。

  • 关键点
    • 默认阈值long_query_time 默认值为 10秒,表示运行时间超过10秒的SQL会被记录。
    • 默认状态:MySQL 默认未开启慢查询日志,需要手动启用。
    • 日志存储方式:支持存储为文件或表。

慢查询日志的相关参数

MySQL慢查询日志的核心参数及其含义如下:

  1. 启用和路径配置

    • slow_query_log:是否开启慢查询日志,1 表示开启,0 表示关闭。
    • slow-query-log-file:日志文件路径和名称(MySQL 5.6及以上版本)。
    • log-slow-queries:旧版(MySQL 5.6以下)的日志存储路径参数。
  2. 时间阈值

    • long_query_time:慢查询的时间阈值,单位是秒。运行时间超过该阈值的查询将被记录到慢查询日志中。
  3. 其他参数

    • log_queries_not_using_indexes:未使用索引的查询也会记录到慢查询日志中,帮助识别潜在的索引问题(可选)
    • log_output:定义日志的存储方式:
      • 'FILE':将日志写入文件(默认)。
      • 'TABLE':将日志记录到 mysql.slow_log 表中。
      • 'FILE,TABLE':同时使用文件和表存储。

如何启用慢查询日志?

方式一:修改配置文件
  1. 打开 MySQL 配置文件(my.cnfmy.ini)。
  2. 添加以下配置:
    slow_query_log = 1
    slow_query_log_file = /path/to/mysql-slow.log
    long_query_time = 2
    log_queries_not_using_indexes = 1
    log_output = 'FILE'
    
  3. 重启 MySQL 服务以生效。
方式二:通过命令动态启用

使用 MySQL 提供的全局变量来开启慢查询日志:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;
SET GLOBAL log_queries_not_using_indexes = 1;
SET GLOBAL log_output = 'FILE';

注意:动态配置的参数在重启后失效,需将参数写入配置文件以持久化。


分析慢查询日志

方式一:直接查看日志文件

慢查询日志文件以文本格式存储,可以使用 cattail 或日志分析工具查看。

方式二:使用EXPLAIN分析查询

EXPLAIN 命令用于模拟优化器的查询执行计划,帮助分析SQL语句的性能问题。
例如:

EXPLAIN SELECT * FROM res_user ORDER BY modifiedtime LIMIT 0,1000;
  • EXPLAIN列说明

    • table:查询涉及的表。
    • type:访问类型,从高到低依次为:consteq_refrefrangeindexALL
    • rows:预计扫描的行数。
    • key:使用的索引。
    • Extra:补充信息,比如是否使用了临时表或文件排序。
  • type 的类型和效率

    1. ALL:全表扫描,效率最低。
    2. index:全索引扫描。
    3. range:索引范围扫描。
    4. ref:非唯一索引扫描或唯一索引前缀扫描。
    5. eq_ref:唯一索引扫描,效率较高。
    6. const/system:常量查询,效率最高。

常见的慢查询优化

优化 MySQL 的慢查询是提升数据库性能的关键环节。以下是常见的慢查询优化方法,按步骤和具体技术进行详细介绍:

1. 数据类型优化
  • 使用占用空间更小的字段类型:
    • 优先使用 TINYINTSMALLINT,而非 INT
    • 固定长度的字符串使用 CHAR,而非 VARCHAR
    • 使用 TIMESTAMP 而非 DATETIME,减少存储空间。
      • TIMESTAMP 占用 4 字节,而 DATETIME 占用 8 字节。TIMESTAMP 的时间范围为 1970-2038,而 DATETIME 为 1000-9999,TIMESTAMP 更节省空间并且在 UTC 时间格式下自动处理时区转换。
    • 精度要求较高时使用 DECIMALBIGINT
      • 如果需要精确的数字存储,特别是涉及到小数的场景,使用 DECIMAL 类型而非 FLOATDOUBLE。例如,对于要求两位小数的金额字段,可以将值乘以 100 保存为 BIGINT
2. 索引优化

索引是优化慢查询最常见和高效的方法。以下是索引优化的几种方式:

  • 创建适合的索引

    • WHERE 子句中频繁使用的列建立索引。
    • GROUP BYORDER BYJOIN 操作中涉及的列建立索引。
    CREATE INDEX idx_column_name ON table_name(column_name);
    
  • 联合索引
    如果查询中涉及多个条件,可以创建联合索引。注意最左前缀原则。

    CREATE INDEX idx_multi_columns ON table_name(column1, column2);
    
  • 覆盖索引
    通过索引覆盖查询的所有字段,减少回表操作。

    SELECT col1, col2 FROM table_name WHERE col1 = 1;
    
  • 避免冗余索引
    合理设计索引,避免不必要的重复索引。例如 (a, b) 的索引已经可以覆盖 a 的查询,没必要再单独为 a 创建索引。


3. SQL 查询优化

优化 SQL 查询语句本身是提高性能的重要手段。

  • 避免 SELECT *
    只查询必要的字段,减少数据传输量。

    SELECT col1, col2 FROM table_name WHERE condition;
    
  • 避免子查询,改用 JOIN
    子查询在某些情况下会导致性能下降,特别是嵌套子查询。

    -- 子查询
    SELECT * FROM table_name WHERE col1 IN (SELECT col1 FROM other_table);-- 改为 JOIN
    SELECT t1.* FROM table_name t1 JOIN other_table t2 ON t1.col1 = t2.col1;
    
  • 合理使用 LIMIT
    对分页查询,尽量使用 LIMIT + 游标(id > n)的方法,减少使用LIMIT + OFFSET 的方式,尤其是当 偏移量(OFFSET)非常大时

    LIMIT + OFFSET 的性能瓶颈

    • 数据库需要从头开始扫描,跳过 OFFSET 指定的记录。
    • 偏移量越大,查询耗时越长。
    • 即使只返回少量数据,数据库仍需加载并跳过大量无关记录。
      示例:
      -- 查询第 1000000 页,每页 10 条记录
      SELECT * FROM orders ORDER BY id DESC LIMIT 1000000, 10;
      
      • 数据库会先找到前 1000000 条记录,跳过它们,然后再返回第 1000000 条后的 10 条记录。
      • 随着 OFFSET 增大,性能会急剧下降。

    优化方案:使用 LIMIT + 游标(id > n)

    • 通过游标条件 id > n,可以直接定位到需要的记录,避免跳过大量无关记录。

      示例:
      假设表 orders 中的主键是 id,查询从第 1000000 条开始的 10 条记录:

      -- 优化后的查询
      SELECT * FROM orders WHERE id > 1000000 ORDER BY id ASC LIMIT 10;
      
      • 通过 id > 1000000 确定游标位置,直接从符合条件的记录开始扫描。
      • 查询性能与 OFFSET 无关,扫描范围大大缩小。
  • 避免函数操作
    不要在 WHERE 子句中对列使用函数,会导致索引失效。

        SELECT * FROM table_name WHERE DATE(column_name) = '2023-01-01'; -- 慢SELECT * FROM table_name WHERE column_name >= '2023-01-01' AND column_name < '2023-01-02'; -- 快
    
  • 减少 OR 的使用
    OR 通常会导致全表扫描,可以用 UNIONIN 代替。

    -- 原始查询:使用 OR,可能导致全表扫描
    SELECT * FROM table_name WHERE col1 = 1 OR col1 = 2;-- 优化方式 1:使用 IN,能够高效利用单列索引
    SELECT * FROM table_name WHERE col1 IN (1, 2);-- 优化方式 2:使用 UNION,将查询拆分成两个独立的部分
    (SELECT * FROM table_name WHERE col1 = 1)
    UNION
    (SELECT * FROM table_name WHERE col1 = 2);
    
  • 优化 LIKE 查询
    LIKE 查询如果以 % 开头会导致全表扫描,因为无法使用索引。可以优化为前缀匹配或使用全文索引。

    示例:

    -- 非优化:前缀为 %,无法使用索引
    SELECT * FROM table_name WHERE col1 LIKE '%keyword%';-- 优化:前缀匹配,能够使用索引
    SELECT * FROM table_name WHERE col1 LIKE 'keyword%';-- 使用全文索引(适用于大文本字段)
    ALTER TABLE table_name ADD FULLTEXT(col1);
    SELECT * FROM table_name WHERE MATCH(col1) AGAINST('keyword');
    
4. 分库分表

分库分表是一种应对大规模数据存储和高并发访问的解决方案。

  • 何时分库分表
    根据《阿里巴巴 Java 开发手册》的建议,单表行数超过 500 万行或单表容量超过 2GB 时,考虑分库分表。

  • 分库分表的好处

    • 提升查询效率:通过拆分单表或数据库,将数据分散到多个存储节点上,减少单节点的存储和查询压力。
    • 提升并发性能:多个节点可以同时处理查询或写入操作,分担压力。
    • 减少锁冲突:分库分表后,每个表的并发操作减少,减少锁等待和冲突。
  • 分库分表的方式

    1. 垂直拆分(按功能分库):
      按业务模块划分数据库,将不同的业务表存储在不同的库中。

      库1:用户数据(users, profiles)
      库2:订单数据(orders, order_items)
      库3:商品数据(products, categories)
      
    2. 水平拆分(按数据分片分库分表):
      将单表数据按照一定规则(如用户 ID、订单 ID 等)拆分到多个表或库中。

      • 范围分片:根据 ID 范围分配数据。
        orders_0: ID 1-10000
        orders_1: ID 10001-20000
        
      • 哈希分片:对分片键取模,将数据分散到多个库或表中。
        -- 按订单 ID 取模分表
        SELECT * FROM orders_hash WHERE MOD(order_id, 4) = 0;
        
  • 分库分表的注意事项

    • 尽量在当前架构下优化数据库性能,例如升级硬件、迁移历史数据。
    • 分片键的选择要能有效分散数据,同时能支持大部分查询需求。
    • 使用分布式中间件(如 ShardingSphere、MyCAT)来管理分库分表后的复杂性。

慢查询日志的适用场景

  1. 数据库性能调优
    • 找出执行较慢的查询,优化索引设计或SQL语句。
  2. 排查系统瓶颈
    • 通过 log_queries_not_using_indexes 找出未使用索引的查询,优化数据访问路径。
  3. 数据模型优化
    • 分析慢查询日志,可以评估表设计、字段类型是否合理。

慢查询日志的优缺点

  • 优点

    • 帮助识别性能瓶颈。
    • 提供查询优化的方向。
    • 支持将日志存储为表,便于后续分析。
  • 缺点

    • 开启后可能对性能产生一定影响,尤其是高并发场景。
    • 日志文件可能过大,需要定期清理。

总结

慢查询日志是性能调优的重要工具,通过合理的日志配置和日志分析,可以有效发现并优化SQL查询性能问题。然而,在高并发环境下,应根据需求合理开启并定期清理日志,避免对数据库性能造成额外负担。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaEE初阶————计算机是如何工作的

今天给大家带来javaEE初阶的知识&#xff0c;相信大家已经学完javaSE了吧&#xff0c;我们从本期博客开始为大家一一讲解&#xff0c;我们现在开始吧 我们作为程序员&#xff0c;大概了解这部分即可嗷 1&#xff0c;计算机的组成 祖师爷提出的&#xff1a; 冯诺依曼体系结构…

基于AI大模型的医院SOP优化:架构、实践与展望

一、引言 1.1 研究背景与意义 近年来,人工智能(AI)技术取得了迅猛发展,尤其是大模型的出现,为各个领域带来了革命性的变化。在医疗领域,AI 医疗大模型正逐渐崭露头角,展现出巨大的应用潜力。随着医疗数据的海量积累以及计算能力的大幅提升,AI 医疗大模型能够对复杂的…

【论文阅读-思维链的构造方法02】4.1.2 Automatic Construction-01

提示1&#xff1a;本篇博客中涉及4篇相关论文&#xff0c;预计阅读时间10分钟&#xff0c;望各位友友耐心阅读&#xff5e; 提示2&#xff1a;本篇所有涉及的论文已打包发布&#xff0c;不需要任何积分即可下载&#xff0c;指路 --> 论文集下载地址 大模型技术-思维链CoT …

uniapp——微信小程序,从客户端会话选择文件

微信小程序选择文件 文章目录 微信小程序选择文件效果图选择文件返回数据格式 API文档&#xff1a; chooseMessageFile 微信小程序读取文件&#xff0c;请查看 效果图 选择文件 /*** description 从客户端会话选择文件* returns {String} 文件路径*/ const chooseFile () &g…

Android GameActivity(NativeActivity)读写文件

最近研究native android相关内容&#xff0c;其中最棘手的就是文件读写问题&#xff0c;最主要的是相关的文档很少。这里写下我所知道的方法。 由于本人使用的是Android14[arm64-v8a]版本的设备,能访问的路径相当有限&#xff0c;如果想要访问更多的路径&#xff0c;就不得不申…

YOLO11改进 | 卷积模块 | ECCV2024 小波卷积

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文给大家带来的教程是将YOLO11的Conv替…

从0开始的opencv之旅(1)cv::Mat的使用

目录 Mat 存储方法 创建一个指定像素方式的图像。 尽管我们完全可以把cv::Mat当作一个黑盒&#xff0c;但是笔者的建议是仍然要深入理解和学习cv::Mat自身的构造逻辑和存储原理&#xff0c;这样在查找问题&#xff0c;或者是遇到一些奇奇怪怪的图像显示问题的时候能够快速的想…

【Hadoop】Hadoop安全之Knox网关

目录 一、概述 2.1 knox介绍 2.2 版本信息 二、部署 三、验证Knox网关 3.1 Hdfs RESTFULL 3.2 HDFSUI 3.3 YARNUI 3.4 HBASEUI 一、概述 2.1 knox介绍 Apache Knox网关是一个用于与Apache Hadoop部署的REST api和ui交互的应用程序网关。Knox网关为所有与Apache Hadoop…

走方格(蓝桥杯2020年试题H)

【问题描述】在平面上有一些二维点阵。这些点的编号就像二维数组的编号一样&#xff0c;从上到下依次为第1~n行&#xff0c;从左到右依次为第1~m列&#xff0c;每个点可以用行号和列号表示。 现在有个人站在第1行第1列&#xff0c;他要走到第n行第m列&#xff0c;只能向右或者向…

uniapp Stripe 支付

引入 Stripe npm install stripe/stripe-js import { loadStripe } from stripe/stripe-js; Stripe 提供两种不同类型组件 Payment Element 和 Card Element&#xff1a;如果你使用的是 Payment Element&#xff0c;它是一个更高级别的组件&#xff0c;能够自动处理多种支…

Visual Studio 2022安装教程

1、下载网址 Visual Studio 2022 IDE安装网址借助 Visual Studio 设计&#xff0c;具有自动完成、构建、调试、测试功能的代码将与 Git 管理和云部署融为一体。https://visualstudio.microsoft.com/zh-hans/vs/ 点击图片所示 双击运行 2、安装 点击C桌面开发&#xff08;右边…

论文笔记PhotoReg: Photometrically Registering 3D Gaussian Splatting Models

1.abstract 最近推出的3D高斯飞溅(3DGS)&#xff0c;它用多达数百万个原始椭球体来描述场景&#xff0c;可以实时渲染。3DGS迅速声名鹊起。然而&#xff0c;一个关键的悬而未决的问题仍然存在&#xff1a;我们如何将多个3DG融合到一个连贯的模型中&#xff1f;解决这个问题将使…

数据结构(ing)

学习内容 指针 指针的定义&#xff1a; 指针是一种变量&#xff0c;它的值为另一个变量的地址&#xff0c;即内存地址。 指针在内存中也是要占据位置的。 指针类型&#xff1a; 指针的值用来存储内存地址&#xff0c;指针的类型表示该地址所指向的数据类型并告诉编译器如何解…

Synopsys软件基本使用方法

Synopsys软件基本使用方法 1 文件说明2 编译流程3 查看波形4 联合仿真 本文主要介绍Synopsys软件vcs、verdi的基本使用方法&#xff0c;相关文件可从 GitHub下载。 1 文件说明 创建verilog源文件add.v、mult.v、top.vmodule add (input signed [31:0] dina,input signed [3…

软件测试基础详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 “尽早的介入测试&#xff0c;遇到问题的解决成本就越低” 随着软件测试技术的发展&#xff0c;测试工作由原来单一的寻找缺陷逐渐发展成为预防缺陷&#xff0c;…

人工智能知识分享第六天-机器学习_​逻辑回归(Logistic Regression)

简介 在机器学习中&#xff0c;分类问题是一种常见的任务&#xff0c;目标是根据输入特征将数据点分配到不同的类别中。为了实现分类&#xff0c;我们需要训练一个分类器&#xff0c;该分类器能够根据输入数据的特征进行预测。 逻辑回归&#xff08;Logistic Regression&…

OpenCV-Python实战(11)——边缘检测

一、Sobel 算子 通过 X 梯度核与 Y 梯度核求得图像在&#xff0c;水平与垂直方向的梯度。 img cv2.Sobel(src*,ddepth*,dx*,dy*,ksize*,scale*,delta*,borderType*)img&#xff1a;目标图像。 src&#xff1a;原始图像。 ddepth&#xff1a;目标图像深度&#xff0c;-1 代表…

Docker- Unable to find image “hello-world“locally

Docker- Unable to find image “hello-world“locally 文章目录 Docker- Unable to find image “hello-world“locally问题描述一. 切换镜像1. 编辑镜像源2. 切换镜像内容 二、 检查设置1、 重启dockers2、 检查配置是否生效3. Docker镜像源检查4. Dokcer执行测试 三、自定义…

【UE5 C++课程系列笔记】19——通过GConfig读写.ini文件

步骤 1. 新建一个Actor类&#xff0c;这里命名为“INIActor” 2. 新建一个配置文件“Test.ini” 添加一个自定义配置项 3. 接下来我们在“INIActor”类中获取并修改“CustomInt”的值。这里定义一个方法“GetINIVariable” 方法实现如下&#xff0c;其中第16行代码用于构建配…

互慧-急诊综合管理平台 ServicePage.aspx 任意文件读取漏洞复现

0x01 产品简介 互慧急诊急救快速联动平台,是用于管理门诊急诊病人的系统,主要包括门诊急诊业务和急诊物资管理两部分,其中门诊急诊业务主要包括院前急救、院内抢救、留观监护、绿色通道、预检分诊等;急诊物资管理包括急诊药品管理、急诊设备管理、抢救车管理、急救箱管理、…