上一篇
场景引入:
"小王最近接手了一个电商项目,后台统计报表越来越慢,尤其是那个「热销商品排行榜」查询,居然要8秒才能出结果!😱 用户投诉不断,经理天天催,怎么办?"
别急!今天我们就来聊聊MySQL子查询的高效玩法,特别是带ORDER BY
时的性能提升技巧,让你的查询速度提升N个档次!🚀
子查询就是嵌套在查询里的查询,
SELECT * FROM products WHERE category_id IN ( SELECT id FROM categories WHERE name = '电子产品' );
看起来很直观对吧?但稍不注意就会变成性能黑洞!💣
ORDER BY
时,可能全表扫描 SELECT * FROM orders WHERE id IN ( SELECT order_id FROM order_items GROUP BY order_id ORDER BY SUM(quantity) DESC LIMIT 10 );
问题:先排序再过滤,MySQL可能先处理整个order_items
表
SELECT o.* FROM orders o JOIN ( SELECT order_id, SUM(quantity) as total_qty FROM order_items GROUP BY order_id ORDER BY total_qty DESC LIMIT 10 ) AS top_orders ON o.id = top_orders.order_id ORDER BY top_orders.total_qty DESC; -- 注意这里!
💡 技巧:内层查询只计算聚合值,外层关联获取完整数据
SELECT * FROM ( SELECT o.*, (SELECT SUM(quantity) FROM order_items WHERE order_id = o.id) as total_qty FROM orders o ) AS order_with_qty ORDER BY total_qty DESC LIMIT 10;
🌟 优势:现代MySQL版本对派生表优化更好
80%的子查询可以用JOIN重写,
-- 代替 WHERE IN (SELECT...) SELECT p.* FROM products p JOIN categories c ON p.category_id = c.id WHERE c.name = '电子产品';
把依赖外层查询的子查询改为派生表:
-- 优化前(慢) SELECT name, (SELECT COUNT(*) FROM orders WHERE user_id = users.id) FROM users; -- 优化后(快) SELECT u.name, o.order_count FROM users u LEFT JOIN ( SELECT user_id, COUNT(*) as order_count FROM orders GROUP BY user_id ) o ON u.id = o.user_id;
-- ❌ 低效(先排序全部再取10条) SELECT * FROM table1 WHERE id IN ( SELECT id FROM table2 ORDER BY score DESC LIMIT 10 ); -- ✅ 高效(先取10条再关联) SELECT t1.* FROM table1 t1 JOIN (SELECT id FROM table2 ORDER BY score DESC LIMIT 10) t2 ON t1.id = t2.id;
确保子查询中的排序字段和关联字段有索引:
-- 给order_items添加复合索引 ALTER TABLE order_items ADD INDEX (order_id, quantity);
用100万条订单数据测试:
查询方式 | 执行时间 |
---|---|
原始子查询+ORDER BY | 2秒 |
优化后的JOIN方案 | 3秒 |
派生表方案 | 5秒 |
提升14倍! 🎉
下次写子查询时,问问自己:
数据库优化没有银弹,多测试、多分析EXPLAIN结果才是王道!💪
(本文基于MySQL 8.0最佳实践,最后更新:2025年8月)
本文由 犁若云 于2025-08-01发表在【云服务器提供商】,文中图片由(犁若云)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/505781.html
发表评论