当前位置: 首页 > news >正文

Mysql篇(三):SQL优化经验全方位解析

MySQL篇(三):SQL优化经验全方位解析

  • MySQL篇(三):SQL优化经验全方位解析
    • 一、SQL查询优化经验
      • (一)合理使用查询条件
      • (二)JOIN操作优化
      • (三)子查询与连接查询的选择
    • 二、创建表时的优化策略
      • (一)字段设计优化
      • (二)存储引擎选择
      • (三)表结构规范化与反规范化
    • 三、索引使用优化经验
      • (一)索引创建原则
      • (二)索引优化策略
    • 四、日常SQL语句优化实践
      • (一)使用执行计划分析
      • (二)慢查询优化
      • (三)事务优化

MySQL篇(三):SQL优化经验全方位解析

一、SQL查询优化经验

(一)合理使用查询条件

  1. 避免select *
    实际开发中,SELECT *会增加数据传输与解析开销。
    • 反例
      -- 获取用户信息时返回所有字段,包含冗余数据  
      SELECT * FROM users;  
      
    • 正例
      -- 只查询必要字段,减少数据量  
      SELECT user_id, user_name, email FROM users;  
      
  2. 优化where条件
    • 使用合适的比较操作符:根据需求选择精准操作符,如查询年龄大于30的用户:
      SELECT * FROM users WHERE age > 30;  
      
    • 避免函数操作在查询条件字段上:对字段使用函数会导致索引失效,可用范围查询替代:
      -- 反例:对字段使用函数,索引失效  
      SELECT * FROM orders WHERE YEAR(order_date) = 2024;  
      -- 正例:通过范围查询替代  
      SELECT * FROM orders WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01';  
      

(二)JOIN操作优化

  1. 选择合适的JOIN类型
    • 明确JOIN目的INNER JOIN用于获取匹配记录,LEFT JOIN保留左表所有记录。
      -- INNER JOIN:获取有订单的用户  
      SELECT u.user_name, o.order_id  
      FROM users u  
      INNER JOIN orders o ON u.user_id = o.user_id;  
      -- LEFT JOIN:获取所有用户及其订单(包括无订单用户)  
      SELECT u.user_name, o.order_id  
      FROM users u  
      LEFT JOIN orders o ON u.user_id = o.user_id;  
      
    • 避免不必要的JOIN:减少JOIN表数量,降低关联复杂度。
  2. 确保JOIN字段有索引
    对JOIN关联字段创建索引,提升效率:
    -- 为orders表的user_id创建索引  
    CREATE INDEX idx_orders_user_id ON orders (user_id);  
    

(三)子查询与连接查询的选择

  1. 评估子查询和连接查询的性能
    • 子查询适用场景:逻辑清晰,适合简单查询。
      -- 子查询:获取订单金额高于平均金额的订单  
      SELECT * FROM orders  
      WHERE order_amount > (SELECT AVG(order_amount) FROM orders);  
      
    • 连接查询适用场景:多表关联且数据量大时性能更优。
      -- 连接查询:获取用户及其订单总金额  
      SELECT u.user_name, SUM(o.order_amount) AS total_amount  
      FROM users u  
      LEFT JOIN orders o ON u.user_id = o.user_id  
      GROUP BY u.user_id;  
      

二、创建表时的优化策略

(一)字段设计优化

  1. 选择合适的数据类型
    • 数值类型:根据数据范围选择,如用户年龄用TINYINT
      CREATE TABLE users (  
          user_id INT PRIMARY KEY,  
          age TINYINT  
      );  
      
    • 字符串类型VARCHAR用于长度不确定的字符串,CHAR用于固定长度(如MD5值):
      CREATE TABLE user_credentials (  
          md5_hash CHAR(32)  
      );  
      
  2. 避免可为空的字段
    设置字段为NOT NULL,提升处理效率:
    -- 反例:email字段允许为空,增加复杂度  
    CREATE TABLE users (  
        email VARCHAR(100)  
    );  
    -- 正例:设置email为NOT NULL  
    CREATE TABLE users (  
        email VARCHAR(100) NOT NULL  
    );  
    

(二)存储引擎选择

  1. InnoDB引擎
    • 适用场景:支持事务、外键,适合OLTP场景(如电商订单系统):
      CREATE TABLE orders (  
          order_id INT PRIMARY KEY,  
          user_id INT,  
          FOREIGN KEY (user_id) REFERENCES users(user_id)  
      ) ENGINE = InnoDB;  
      
    • 优势:数据安全高,支持行级锁,并发性能好。
  2. MyISAM引擎
    • 适用场景:读多写少,对事务要求不高(如日志记录):
      CREATE TABLE access_logs (  
          log_id INT PRIMARY KEY,  
          access_time DATETIME  
      ) ENGINE = MyISAM;  
      
    • 优势:查询性能高,存储结构简单。

(三)表结构规范化与反规范化

  1. 规范化表结构
    • 减少数据冗余:遵循范式设计,如用户表与订单表分离:
      -- 用户表  
      CREATE TABLE users (  
          user_id INT PRIMARY KEY,  
          user_name VARCHAR(50),  
          email VARCHAR(100)  
      );  
      -- 订单表  
      CREATE TABLE orders (  
          order_id INT PRIMARY KEY,  
          user_id INT,  
          FOREIGN KEY (user_id) REFERENCES users(user_id)  
      );  
      
    • 优点:数据一致性高,易于维护。
  2. 反规范化处理
    • 提升查询性能:适当增加冗余字段减少JOIN。如订单表添加用户姓名:
      CREATE TABLE orders (  
          order_id INT PRIMARY KEY,  
          user_id INT,  
          user_name VARCHAR(50), -- 冗余字段  
          FOREIGN KEY (user_id) REFERENCES users(user_id)  
      );  
      
    • 适用场景:读多写少,对查询性能要求高的场景。

三、索引使用优化经验

(一)索引创建原则

  1. 基于查询频率创建
    WHEREORDER BYGROUP BY字段创建索引:
    -- 为查询条件age字段创建索引  
    CREATE INDEX idx_age ON users (age);  
    -- 为排序字段order_date创建索引  
    CREATE INDEX idx_order_date ON orders (order_date);  
    
  2. 组合索引的创建
    遵循最左匹配原则,如查询WHERE country = 'China' AND city = 'Beijing'
    CREATE INDEX idx_country_city ON addresses (country, city);  
    

(二)索引优化策略

  1. 避免过多索引
    过多索引影响写性能,定期评估并删除冗余索引:
    -- 删除冗余索引  
    DROP INDEX idx_useless ON table_name;  
    
  2. 使用覆盖索引
    确保索引包含查询字段,避免回表:
    -- 创建覆盖索引  
    CREATE INDEX idx_user_id_name ON users (user_id, user_name);  
    -- 查询语句(无需回表)  
    SELECT user_id, user_name FROM users WHERE age > 30;  
    

四、日常SQL语句优化实践

(一)使用执行计划分析

  1. EXPLAIN关键字
    通过EXPLAIN分析执行计划,查看索引使用:
    EXPLAIN SELECT * FROM users WHERE age > 30;  
    
    • 关键列分析
      • type:连接类型,consteq_ref为优,indexALL需优化。
      • key:显示使用的索引。
      • rows:预估扫描行数,越小越好。

(二)慢查询优化

  1. 慢查询日志分析
    开启慢查询日志(配置my.cnf):
    [mysqld]  
    slow_query_log = 1  
    slow_query_log_file = /var/log/mysql/mysql-slow.log  
    long_query_time = 2  
    
    使用mysqldumpslowpt-query-digest分析日志,优化慢查询。
  2. 重构复杂SQL
    将复杂SQL分解为子查询或临时表:
    -- 复杂查询  
    SELECT * FROM a  
    JOIN b ON a.id = b.a_id  
    JOIN c ON b.id = c.b_id;  
    -- 优化:使用临时表  
    CREATE TEMPORARY TABLE temp_b AS  
    SELECT * FROM b;  
    CREATE TEMPORARY TABLE temp_c AS  
    SELECT * FROM c;  
    SELECT * FROM a  
    JOIN temp_b ON a.id = temp_b.a_id  
    JOIN temp_c ON temp_b.id = temp_c.b_id;  
    

(三)事务优化

  1. 控制事务范围
    减少事务内操作,缩短持续时间:
    -- 反例:事务包含大量操作  
    START TRANSACTION;  
    -- 多个查询和更新  
    COMMIT;  
    -- 正例:精简事务内容  
    START TRANSACTION;  
    -- 必要更新  
    COMMIT;  
    
  2. 合理使用事务隔离级别
    根据业务选隔离级别,如读已提交(READ COMMITTED):
    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;  
    START TRANSACTION;  
    -- 事务操作  
    COMMIT;  
    

通过SQL编写、建表设计、索引使用到日常维护的优化,可全面提升数据库性能。实际项目中需结合业务场景,灵活运用优化策略,不断调试以达最佳效果。

相关文章:

  • 武汉做公司网站的公司网络推广公司哪家做得好
  • 网站短信验证码怎么做seo排名点击软件推荐
  • 山西电力建设三公司网站网站推广的常用方法
  • 竞价单页太原网站制作优化seo公司
  • 怎么做有声小说网站播音员最新舆情信息网
  • excel做邮箱网站怎么加3www印度疫情最新消息
  • 算法设计学习7
  • 【Axure元件分享】年月日范围选择器
  • 使用MQTTX软件连接阿里云
  • 基于卷积神经网络CNN实现电力负荷多变量时序预测(PyTorch版)
  • 装饰器(Decorator) 装饰器作用
  • grep 命令详解(通俗版)
  • AQUA爱克泳池设备入驻济南校园,以品质筑牢游泳教育安全防线
  • C# System.Text.Json 中 JsonNamingPolicy 使用详解
  • ue5 仿鬼泣5魂类游戏角色和敌人没有碰撞
  • Opencv计算机视觉编程攻略-第八节 检测兴趣点
  • linux 安装 mysql记录
  • 【机器学习中的基本术语:特征、样本、训练集、测试集、监督/无监督学习】
  • SpringKafka错误处理:重试机制与死信队列
  • WPF设计学习记录滴滴滴4
  • 安装 Microsoft Visual C++ Build Tools
  • 测风塔选址和安装原则
  • Nginx的URL重写及访问控制
  • AI智能体驱动下的营销范式革命:解码“氛围营销“时代的战略重构
  • 《Linux内存管理:实验驱动的深度探索》【附录】【实验环境搭建 2】【vscode搭建调试内核环境】
  • Gemini 2.5 Pro与Claude 3.7 Sonnet编程性能对比