您的位置:首页 > 教育 > 锐评 > 东莞企业营销推广_哈尔滨市建设工程质量安全站_网站查询入口_百度站长平台电脑版

东莞企业营销推广_哈尔滨市建设工程质量安全站_网站查询入口_百度站长平台电脑版

2025/4/3 21:37:29 来源:https://blog.csdn.net/haote_go/article/details/146761175  浏览:    关键词:东莞企业营销推广_哈尔滨市建设工程质量安全站_网站查询入口_百度站长平台电脑版
东莞企业营销推广_哈尔滨市建设工程质量安全站_网站查询入口_百度站长平台电脑版

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com