SQL优化实战:如何让查询速度提升10倍

张开发
2026/4/21 5:28:16 15 分钟阅读

分享文章

SQL优化实战:如何让查询速度提升10倍
前言数据分析师工作中SQL是最核心的技能之一。但很多人的SQL写得很慢查询跑了10分钟还不出结果严重影响工作效率。本文结合实际案例分享SQL优化的核心思路帮助你把查询速度从10分钟优化到1分钟以内。一、为什么SQL会慢SQL查询慢的本质原因只有一个扫描了太多数据。理解这一点所有的优化手段都能推导出来。常见的慢查询原因SELECT * 全表扫描WHERE条件没有索引JOIN没有正确的连接条件GROUP BY/DISTINCT 数据量太大子查询嵌套层数过多二、案例分析订单报表优化2.1 原始查询耗时8分钟SELECT o.order_id, o.user_id, o.order_time, o.amount, u.username, u.city, p.product_name, p.category FROM orders o LEFT JOIN users u ON o.user_id u.user_id LEFT JOIN order_items oi ON o.order_id oi.order_id LEFT JOIN products p ON oi.product_id p.product_id WHERE o.order_time 2025-01-01 AND o.order_time 2026-01-01 AND u.city IN (北京, 上海, 广州, 深圳) ORDER BY o.order_time DESC;2.2 优化思路第一步添加合适的索引-- 为 WHERE 条件字段添加索引 CREATE INDEX idx_orders_time ON orders(order_time); CREATE INDEX idx_orders_user ON orders(user_id); CREATE INDEX idx_users_city ON users(city); -- 为 JOIN 字段添加索引 CREATE INDEX idx_order_items_order ON order_items(order_id); CREATE INDEX idx_products_id ON products(product_id);第二步减少扫描范围-- 先筛选再JOIN减少中间数据量 SELECT o.order_id, o.user_id, o.order_time, o.amount, u.username, u.city, p.product_name, p.category FROM ( -- 先筛选主表 SELECT order_id, user_id, order_time, amount FROM orders WHERE order_time 2025-01-01 AND order_time 2026-01-01 ) o LEFT JOIN ( -- 再筛选用户表 SELECT user_id, username, city FROM users WHERE city IN (北京, 上海, 广州, 深圳) ) u ON o.user_id u.user_id LEFT JOIN order_items oi ON o.order_id oi.order_id LEFT JOIN products p ON oi.product_id p.product_id ORDER BY o.order_time DESC;第三步用EXISTS替代IN适用于子查询-- 优化前IN子查询 SELECT * FROM orders WHERE user_id IN ( SELECT user_id FROM users WHERE city 北京 ); -- 优化后EXISTS SELECT * FROM orders o WHERE EXISTS ( SELECT 1 FROM users u WHERE u.city 北京 AND u.user_id o.user_id );2.3 优化结果优化阶段耗时说明原始查询8分钟全表扫描添加索引3分钟索引生效减少扫描45秒先筛再JOIN最终优化12秒综合优化提升倍数40倍三、常用优化技巧总结3.1 索引优化-- 组合索引遵循最左前缀原则 -- 创建组合索引 CREATE INDEX idx_col1_col2 ON table_name(col1, col2); -- 查询能命中索引的情况 WHERE col1 xxx -- ✅ 命中 WHERE col1 xxx AND col2 yyy -- ✅ 命中 WHERE col2 yyy -- ❌ 不命中 -- 避免在索引列上使用函数 WHERE YEAR(create_time) 2025 -- ❌ 不命中索引 WHERE create_time 2025-01-01 -- ✅ 命中索引3.2 LIMIT分页优化-- 优化前深分页慢 SELECT * FROM orders ORDER BY order_id LIMIT 1000000, 20; -- 优化后基于ID分页 SELECT * FROM orders WHERE order_id 1000000 ORDER BY order_id LIMIT 20;3.3 COUNT优化-- 优化前COUNT * 全表扫描 SELECT COUNT(*) FROM orders WHERE status 1; -- 优化后使用索引计数 SELECT COUNT(1) FROM orders WHERE status 1; -- 或者维护统计表实时性要求不高时四、如何判断SQL性能使用 EXPLAIN 分析执行计划EXPLAIN SELECT * FROM orders WHERE order_time 2025-01-01; -- 关键字段说明 -- type: 连接类型const eq_ref ref range ALL -- key: 实际使用的索引 -- rows: 预计扫描行数 -- Extra: 额外信息Using index, Using filesort等五、总结SQL优化的核心原则减少数据扫描量WHERE条件尽量精确合理使用索引为高频查询字段建索引避免全表扫描不用SELECT *少用函数优化JOIN顺序小表驱动大表分析执行计划用EXPLAIN定位问题记住SQL优化是一个持续的过程没有银弹只有不断分析和迭代。作者简介船长数据分析师关注数据分析、职场成长、投资理财。

更多文章