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

MySQL 高效 SQL 使用技巧详解

MySQL 高效 SQL 使用 技巧详解

一、为什么需要优化 SQL?

  • 性能瓶颈:慢查询导致数据库负载升高,响应时间延长。
  • 资源浪费:低效 SQL 可能占用大量 CPU、内存和磁盘 I/O。
    目标:通过优化 SQL 将查询性能提升 10 倍以上,降低硬件成本。

二、核心优化原则

  1. 索引优先:为高频查询字段添加索引。
  2. 减少数据量:避免全表扫描,缩小查询范围。
  3. 简化逻辑:用 JOIN 替代子查询,避免复杂嵌套。
  4. 事务控制:缩短事务长度,减少锁竞争。

三、高效 SQL 实战技巧

1. 索引优化

(1)创建复合索引
-- 为 (user_id, create_time) 创建复合索引
CREATE INDEX idx_user_time ON orders(user_id, create_time);

适用场景:排序、范围查询(如 BETWEEN)。

(2)覆盖索引
-- 查询字段包含在索引中,避免回表
SELECT user_id, create_time FROM orders WHERE user_id = 100;

索引建议

CREATE INDEX idx_user_time_covering ON orders(user_id, create_time) INCLUDE (status);
(3)避免索引失效
错误写法正确写法原因
WHERE price > 100 OR status = 'paid'WHERE price > 100 AND status = 'paid'OR 导致索引失效
WHERE name LIKE '%test'WHERE name LIKE 'test%'前缀模糊查询可利用索引

2. 查询优化

(1)使用 EXPLAIN 分析执行计划
EXPLAIN SELECT * FROM users WHERE age > 30;

关键指标

  • type: 连接类型(理想值:refeq_ref)。
  • key: 使用的索引(NULL 表示全表扫描)。
  • rows: 预估扫描行数(越小越好)。
(2)分页优化

原查询(慢):

SELECT * FROM products LIMIT 100000, 10;

优化后(利用覆盖索引):

SELECT id, name FROM products 
WHERE id > (SELECT id FROM products LIMIT 100000, 1)
LIMIT 10;
(3)批量操作替代循环

错误写法

for item in data:
    cursor.execute("INSERT INTO logs VALUES (%s)", item)

正确写法

INSERT INTO logs (col1, col2) VALUES 
(1, 'a'), (2, 'b'), (3, 'c');

3. 事务与锁优化

(1)减少锁粒度
-- 行级锁示例(InnoDB 默认)
UPDATE users SET balance = balance - 100 WHERE id = 100;
(2)缩短事务长度

反模式

START TRANSACTION;
SELECT * FROM large_table; -- 耗时操作
UPDATE orders SET status = 'paid';
COMMIT;

优化后

START TRANSACTION;
UPDATE orders SET status = 'paid';
COMMIT;

4. 存储引擎选择

引擎特点适用场景
InnoDB支持事务、行级锁、外键高并发读写(如电商订单)
MyISAM表级锁、不支持事务读多写少(如日志表)
Memory内存存储、速度极快临时数据缓存

四、高级优化技巧

1. 子查询转 JOIN

原查询

SELECT * FROM orders 
WHERE user_id IN (SELECT id FROM users WHERE city = 'Shanghai');

优化后

SELECT o.* 
FROM orders o
JOIN users u ON o.user_id = u.id
WHERE u.city = 'Shanghai';

2. 避免 SELECT *

反模式

SELECT * FROM employees;

正确写法

SELECT id, name, email FROM employees;

3. 使用 LIMIT 限制结果集

-- 快速获取最新记录
SELECT * FROM logs ORDER BY create_time DESC LIMIT 10;

五、实战案例:优化电商订单查询

优化前 SQL

SELECT * FROM orders 
WHERE user_id = 100 AND status = 'paid'
ORDER BY create_time DESC;

问题

  • 全表扫描(无索引)。
  • 回表查询所有字段。

优化步骤

  1. 添加复合索引

    CREATE INDEX idx_user_status_time ON orders(user_id, status, create_time);
    
  2. 仅查询必要字段

    SELECT id, amount, create_time 
    FROM orders 
    WHERE user_id = 100 AND status = 'paid'
    ORDER BY create_time DESC;
    

优化后效果

  • 查询时间:从 2.1 秒降至 0.05 秒。
  • 索引覆盖度:100%(无需回表)。

六、注意事项

1. 索引维护成本

  • 索引过多会降低写入性能。
  • 建议:为查询频率高的字段创建索引。

2. 慢查询日志

-- 开启慢查询日志(超过 2 秒的查询)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;

3. 测试环境验证

# 使用 sysbench 压测
sysbench --test=oltp --oltp-table-size=1000000 --mysql-user=root run

七、总结:高效 SQL 检查表

优化项操作工具/命令
索引使用 EXPLAIN 分析执行计划EXPLAIN
查询避免 SELECT *,使用覆盖索引EXPLAIN
事务缩短事务长度,减少锁竞争监控 InnoDB_row_lock_waits
存储引擎根据场景选择合适引擎SHOW TABLE STATUS
慢查询开启慢查询日志并分析pt-query-digest

相关文章:

  • 6. 王道_网络协议
  • 利用Linux的SPI子系统和SPI总线写出SPI设备(DAC模块)的驱动
  • 精确截图工具:基于 Tkinter 和 PyAutoGUI 的实现
  • Docker实现MySQL主从复制配置【简易版】
  • linux 部署Jumpserver(堡垒机)
  • 音视频(二)ffmpeg编译及推流
  • yum repolist all全部禁用了 怎么办
  • 【Ragflow】6. Ragflow-plus重磅更新:增加用户后台管理系统
  • IIC协议以及STM32IIC的特性和架构
  • Redis-05.Redis常用命令-哈希操作命令
  • 流影---开源网络流量分析平台(三)(管理引擎部署)
  • Redis:事务
  • 2025前端八股文终极指南:从高频考点到降维打击的面试突围战
  • Nginx — Nginx版本升级
  • 美甲预约管理系统基于Spring Boot SSM
  • 如何高效解决 Java 内存泄漏问题方法论
  • (学习总结31)Linux 进程地址空间与进程控制
  • 电子电气架构 --- EEA演进与芯片架构转移
  • vue前端代码作业——待办事项
  • [CSAPP] 9.8 内存映射 | 虚拟内存 | 页表 | 物理内存 | 写时拷贝机制
  • 网络app开发网站建设价格/广州百度推广优化排名
  • 队徽logo设计/长春网站优化页面
  • wordpress做外贸网站的劣势/培训行业seo整站优化
  • 抖音代运营报价明细表/seo课
  • 用flask做网站/网站模板中心
  • 潍坊专业网站建设多少钱/西安百度竞价托管代运营