如何通过SQL子查询构建嵌套逻辑实现复杂业务规则引擎?
- 内容介绍
- 相关推荐
本文共计1018个文字,预计阅读时间需要5分钟。
MySQL 5.7 及更早版本、SQLite、SQL Server 都不支持在 `ORDER BY` 中直接使用子查询。错误信息通常是:
实操建议:
- 把子查询提前到
SELECT列表中,用别名(比如sort_weight),再在ORDER BY sort_weight引用它 - 避免写成
ORDER BY (SELECT COUNT(*) FROM orders WHERE user_id = u.id)—— 这种相关子查询会被主表每行执行一次,数据量一过万就明显变慢 - 如果排序依据需要跨表聚合(比如“按用户最近订单金额降序”),优先用
LEFT JOIN预聚合:先SELECT user_id, COALESCE(SUM(amount), 0) AS total_spent FROM orders GROUP BY user_id,再和主表关联 - 注意
LEFT JOIN后可能产生重复行,记得加DISTINCT或按主键GROUP BY
WHERE 中用 IN 子查询查存在性,为什么越来越慢
当写 SELECT * FROM users WHERE id IN (SELECT user_id FROM orders),小数据量没问题;但 users 表超百万行时,MySQL/PostgreSQL 很可能把它优化成临时表 + 嵌套循环,性能断崖下跌。
本文共计1018个文字,预计阅读时间需要5分钟。
MySQL 5.7 及更早版本、SQLite、SQL Server 都不支持在 `ORDER BY` 中直接使用子查询。错误信息通常是:
实操建议:
- 把子查询提前到
SELECT列表中,用别名(比如sort_weight),再在ORDER BY sort_weight引用它 - 避免写成
ORDER BY (SELECT COUNT(*) FROM orders WHERE user_id = u.id)—— 这种相关子查询会被主表每行执行一次,数据量一过万就明显变慢 - 如果排序依据需要跨表聚合(比如“按用户最近订单金额降序”),优先用
LEFT JOIN预聚合:先SELECT user_id, COALESCE(SUM(amount), 0) AS total_spent FROM orders GROUP BY user_id,再和主表关联 - 注意
LEFT JOIN后可能产生重复行,记得加DISTINCT或按主键GROUP BY
WHERE 中用 IN 子查询查存在性,为什么越来越慢
当写 SELECT * FROM users WHERE id IN (SELECT user_id FROM orders),小数据量没问题;但 users 表超百万行时,MySQL/PostgreSQL 很可能把它优化成临时表 + 嵌套循环,性能断崖下跌。

