如何优化 MySQL 存储过程的性能?

news2025/7/26 8:17:26

在这里插入图片描述

文章目录

    • 1. 优化 SQL 语句
      • 避免全表扫描
      • 减少子查询,改用 JOIN
      • 避免 `SELECT `
    • 2. 合理使用索引
    • 3. 优化存储过程结构
      • 减少循环和临时变量
      • 避免重复计算
    • 4. 使用临时表和缓存
    • 5. 优化事务处理
    • 6. 分析和监控性能
    • 7. 优化数据库配置
    • 8. 避免用户自定义函数(UDF)
    • 9. 分批处理大数据量
    • 性能优化示例

1. 优化 SQL 语句

存储过程的性能往往取决于其中 SQL 语句的效率。

避免全表扫描

确保 WHERE 子句中的条件字段有索引,避免全表扫描:

-- 未优化:可能触发全表扫描
SELECT * FROM orders WHERE order_date > '2023-01-01';

-- 优化:为 order_date 添加索引
CREATE INDEX idx_order_date ON orders (order_date);

减少子查询,改用 JOIN

子查询效率较低,尽量用 JOIN 替代:

-- 未优化:子查询
SELECT * FROM employees 
WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'Beijing');

-- 优化:JOIN
SELECT e.* FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE d.location = 'Beijing';

避免 SELECT

只查询需要的字段,减少数据传输和内存开销:

-- 未优化
SELECT * FROM products;

-- 优化
SELECT product_id, name, price FROM products;

2. 合理使用索引

  • 为经常用于 WHEREJOINORDER BY 的字段添加索引。
  • 避免过度索引,索引会增加写操作的开销。
  • 使用复合索引时,注意字段顺序(最左匹配原则)。
-- 为多条件查询创建复合索引
CREATE INDEX idx_customer_order ON orders (customer_id, order_date DESC);

3. 优化存储过程结构

减少循环和临时变量

循环(如 WHILEFOR)在存储过程中效率较低,尽量用集合操作替代:

-- 未优化:循环逐条更新
WHILE condition DO
    UPDATE products SET stock = stock - 1 WHERE product_id = id;
END WHILE;

-- 优化:批量更新
UPDATE products SET stock = stock - 1 WHERE product_id IN (1, 2, 3, ...);

避免重复计算

将重复使用的计算结果存储在临时变量中:

-- 未优化:重复计算
IF (SELECT COUNT(*) FROM orders WHERE customer_id = 100) > 10 THEN
    -- 再次查询相同条件
    SELECT SUM(amount) FROM orders WHERE customer_id = 100;
END IF;

-- 优化:使用临时变量
DECLARE order_count INT;
SELECT COUNT(*) INTO order_count FROM orders WHERE customer_id = 100;

IF order_count > 10 THEN
    SELECT SUM(amount) FROM orders WHERE customer_id = 100;
END IF;

4. 使用临时表和缓存

对于复杂查询,使用临时表存储中间结果,避免重复计算:

DELIMITER $$

CREATE PROCEDURE GetSalesReport()
BEGIN
    -- 创建临时表存储中间结果
    CREATE TEMPORARY TABLE temp_sales (
        product_id INT,
        total_sales DECIMAL(10,2)
    );
    
    -- 插入中间结果
    INSERT INTO temp_sales
    SELECT product_id, SUM(amount) FROM orders GROUP BY product_id;
    
    -- 使用临时表进行最终查询
    SELECT p.name, t.total_sales 
    FROM products p
    JOIN temp_sales t ON p.product_id = t.product_id;
    
    -- 删除临时表
    DROP TEMPORARY TABLE IF EXISTS temp_sales;
END$$

DELIMITER ;

5. 优化事务处理

  • 保持事务简短,减少锁持有时间。
  • 避免在事务中进行耗时操作(如文件读写、网络请求)。
DELIMITER $$

CREATE PROCEDURE TransferFunds(IN from_account INT, IN to_account INT, IN amount DECIMAL(10,2))
BEGIN
    START TRANSACTION;
    
    -- 快速执行更新操作
    UPDATE accounts SET balance = balance - amount WHERE account_id = from_account;
    UPDATE accounts SET balance = balance + amount WHERE account_id = to_account;
    
    COMMIT;
END$$

DELIMITER ;

6. 分析和监控性能

  • 使用 EXPLAIN 分析 SQL 语句的执行计划,检查是否使用了索引:

    EXPLAIN SELECT * FROM orders WHERE customer_id = 100;
    
  • 使用 SHOW PROFILE 查看存储过程的详细执行时间:

    SET profiling = 1;
    CALL CalculateTotal(1001);
    SHOW PROFILES;
    SHOW PROFILE FOR QUERY 1;  -- 查询 ID 可从 SHOW PROFILES 结果中获取
    

7. 优化数据库配置

根据服务器硬件调整 MySQL 配置参数,例如:

  • innodb_buffer_pool_size:增大缓冲池大小,减少磁盘 I/O。
  • sort_buffer_size:调整排序缓冲区大小,优化排序操作。
  • max_connections:根据并发需求调整最大连接数。

8. 避免用户自定义函数(UDF)

用户自定义函数(尤其是用 Python 或 C 编写的外部 UDF)会显著降低性能,尽量用内置函数替代。

9. 分批处理大数据量

对于大数据集操作,分批处理以减少内存占用:

DELIMITER $$

CREATE PROCEDURE ProcessLargeData()
BEGIN
    DECLARE offset INT DEFAULT 0;
    DECLARE batch_size INT DEFAULT 1000;
    DECLARE total_rows INT;
    
    -- 获取总记录数
    SELECT COUNT(*) INTO total_rows FROM large_table;
    
    WHILE offset < total_rows DO
        -- 分批处理
        UPDATE large_table 
        SET status = 'processed' 
        WHERE id BETWEEN offset AND offset + batch_size;
        
        SET offset = offset + batch_size;
    END WHILE;
END$$

DELIMITER ;

性能优化示例

假设有一个存储过程查询订单总金额,但性能较差:

DELIMITER $$

CREATE PROCEDURE GetOrderTotal(IN customerId INT)
BEGIN
    -- 未优化:全表扫描 + 子查询
    SELECT 
        customer_id,
        (SELECT COUNT(*) FROM orders WHERE customer_id = c.customer_id) AS order_count,
        (SELECT SUM(amount) FROM orders WHERE customer_id = c.customer_id) AS total_amount
    FROM customers c
    WHERE c.customer_id = customerId;
END$$

DELIMITER ;

优化后:

DELIMITER $$

CREATE PROCEDURE GetOrderTotal(IN customerId INT)
BEGIN
    -- 优化:JOIN + 索引 + 聚合函数
    SELECT 
        c.customer_id,
        COUNT(o.order_id) AS order_count,
        SUM(o.amount) AS total_amount
    FROM customers c
    LEFT JOIN orders o ON c.customer_id = o.customer_id
    WHERE c.customer_id = customerId
    GROUP BY c.customer_id;
END$$

DELIMITER ;

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

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

相关文章

创新点!贝叶斯优化、CNN与LSTM结合,实现更准预测、更快效率、更高性能!

能源与环境领域的时空数据预测面临特征解析与参数调优双重挑战。CNN-LSTM成为突破口&#xff1a;CNN提取空间特征&#xff0c;LSTM捕捉时序依赖&#xff0c;实现时空数据的深度建模。但混合模型超参数&#xff08;如卷积核数、LSTM层数&#xff09;调优复杂&#xff0c;传统方法…

【Flutter】创建BMI计算器应用并添加依赖和打包

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍创建BMI计算器应用并添加依赖和打包。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

【Linux 学习计划】-- 倒计时、进度条小程序

目录 \r 、\n、fflush 倒计时 进度条 进度条进阶版 结语 \r 、\n、fflush 首先我们先来认识这三个东西&#xff0c;这将会是我们接下来两个小程序的重点之一 首先是我们的老演员\n&#xff0c;也就是回车加换行 这里面其实包含了两个操作&#xff0c;一个叫做回车&…

微服务的应用案例

从“菜市场”到“智慧超市”&#xff1a;一场微服务的变革之旅 曾经&#xff0c;我们的系统像一个熙熙攘攘的传统菜市场。所有功能模块&#xff08;摊贩&#xff09;都挤在一个巨大的单体应用中。用户请求&#xff08;买菜的顾客&#xff09;一多&#xff0c;整个市场就拥堵不堪…

2025网络安全趋势报告 内容摘要

2025 年网络安全在技术、法规、行业等多个维度呈现新趋势。技术上&#xff0c;人工智能、隐私保护技术、区块链、量子安全技术等取得进展&#xff1b;法规方面&#xff0c;数据安全法规进一步细化&#xff1b;行业应用中&#xff0c;物联网、工业控制系统安全升级&#xff0c;供…

云原生安全基石:深度解析HTTPS协议(从原理到实战)

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念&#xff1a;HTTPS是什么&#xff1f; HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;是HTTP协议的安全版本&#xff0c…

Autodl训练Faster-RCNN网络--自己的数据集(一)

参考文章&#xff1a; Autodl服务器中Faster-rcnn(jwyang)复现(一)_autodl faster rcnn-CSDN博客 Autodl服务器中Faster-rcnn(jwyang)训练自己数据集(二)_faster rcnn autodl-CSDN博客 食用指南&#xff1a;先跟着参考文章一进行操作&#xff0c;遇到问题再来看我这里有没有解…

python打卡day36

复习日 仔细回顾一下神经网络到目前的内容&#xff0c;没跟上进度的补一下进度 作业&#xff1a;对之前的信贷项目&#xff0c;利用神经网络训练下&#xff0c;尝试用到目前的知识点让代码更加规范和美观。探索性作业&#xff08;随意完成&#xff09;&#xff1a;尝试进入nn.M…

Paimon和Hive相集成

Flink版本1.17 Hive版本3.1.3 1、Paimon集成Hive 将paimon-hive-connector.jar复制到auxlib中&#xff0c;下载链接Index of /groups/snapshots/org/apache/https://repository.apache.org/snapshots/org/apache/paimon/ 通过flink进入查看paimon /opt/softwares/flink-1.…

HarmonyOS 鸿蒙应用开发进阶:深入理解鸿蒙跨设备互通机制

鸿蒙跨设备互通&#xff08;HarmonyOS Cross-Device Collaboration&#xff09;是鸿蒙系统分布式能力的重要体现&#xff0c;通过创新的分布式软总线技术&#xff0c;实现了设备间的高效互联与能力共享。本文将系统性地解析鸿蒙跨设备互通的技术架构、实现原理及开发实践。 跨设…

Vue.js教学第十五章:深入解析Webpack与Vue项目实战

Webpack 与 Vue 项目详解 在现代前端开发中,Webpack 作为最流行的模块打包工具之一,对于 Vue 项目的构建和优化起着至关重要的作用。本文将深入剖析 Webpack 的基本概念、在 Vue 项目中的应用场景,并详细讲解常用的 Webpack loaders 和 plugins 的配置与作用,同时通过实例…

Cmake编译gflags过程记录和在QT中测试

由于在QT中使用PaddleOCR2.8存在这样那样的问题&#xff0c;查找貌似是gflags相关问题导致的&#xff0c;因此从头开始按相关参考文章编译一遍gflags源码&#xff0c;测试结果表明Qt5.14.2中使用MSVC2017X64编译器运行的QTgflags项目是正常。 详细编译步骤如下&#xff1a; 1、…

项目中Warmup耗时高该如何操作处理

1&#xff09;项目中Warmup耗时高该如何操作处理 2&#xff09;如何在卸载资源后Untracked和Other的内存都回收 3&#xff09;总Triangles的值是否包含了通过GPU Instancing画的三角形 4&#xff09;有没有用Lua来修复虚幻引擎中对C代码进行插桩Hook的方案 这是第432篇UWA技术知…

制作一款打飞机游戏53:子弹样式

现在&#xff0c;我们有一个小程序可以发射子弹&#xff0c;但这些子弹并不完美&#xff0c;我们稍后会修复它们。 子弹模式与目标 在开始之前&#xff0c;我想修正一下&#xff0c;因为我观察到在其他射击游戏中有一个我想复制的简单行为。我们有静态射击、瞄准射击和快速射击…

Docker运维-5.3 配置私有仓库(Harbor)

1. harbor的介绍 Harbor(港湾)&#xff0c;是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器。以前的镜像私有仓库采用官方的 Docker Registry&#xff0c;不便于管理镜像。 Harbor 是由 VMWare 在 Docker Registry 的基础之上进行了二次封装&#xff0c;加进去了很…

day 36

利用前面所学知识&#xff0c;对之前的信贷项目&#xff0c;利用神经网络训练 # 先运行之前预处理好的代码 import pandas as pd import pandas as pd #用于数据处理和分析&#xff0c;可处理表格数据。 import numpy as np #用于数值计算&#xff0c;提供了高效的数组…

mybatis-plus使用记录

MyBatis-Plus 学习笔记 一、 快速入门 MyBatis-Plus (MP) 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 1. 引入 Maven 依赖 要使用 MyBatis-Plus&#xff0c;首先需要在项目的 pom.xml 文件中引入相…

Mcu_Bsdiff_Upgrade

系统架构 概述 MCU BSDiff 升级系统通过使用二进制差分技术&#xff0c;提供了一种在资源受限的微控制器上进行高效固件更新的机制。系统不传输和存储完整的固件映像&#xff0c;而是只处理固件版本之间的差异&#xff0c;从而显著缩小更新包并降低带宽要求。 该架构遵循一个…

有监督学习——决策树

任务 1、基于iris_data.csv数据&#xff0c;建立决策树模型&#xff0c;评估模型表现; 2、可视化决策树结构; 3、修改min_samples_leaf参数&#xff0c;对比模型结果 代码工具&#xff1a;jupyter notebook 参考资料 20.23 决策树&#xff08;1&#xff09;_哔哩哔哩_bil…

华为OD机试真题——启动多任务排序(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…