在 Oracle 里,写 SQL 想要更高效,核心并不是'记住某个固定顺序',而是尽量让优化器更容易把结果集缩小。很多时候,条件写法、连接方式和索引是否能被用上,比字面上的先后顺序更重要。
一些常见的写法习惯
1. 让过滤尽早发生
如果一张表的数据量明显更大,通常希望先把它的结果集尽可能过滤掉,再去做关联。这样做的目的很简单:减少后续要参与计算的数据量。
不过要注意,SQL 不是按人写的顺序机械执行的,Oracle 会由优化器决定执行计划。也就是说,真正决定效率的不是'我先写谁',而是优化器能不能根据统计信息、索引和条件选择到合适的访问路径。
-- A 表数据多,B 表数据少
SELECT *
FROM A a
JOIN B b ON a.id = b.id
WHERE ...;
写关联查询时,尽量把过滤条件明确写出来,让优化器有机会先缩小数据范围。别依赖'表写在前面还是后面'这种表面顺序,重点是让条件足够清楚。
2. 优先写选择性更高的条件
如果多个条件一起过滤,通常把选择性更高、能更快缩小结果集的条件写清楚更有价值。比如等值条件通常比范围条件更容易利用索引,具体能不能走索引,还要看索引设计、统计信息和执行计划。
SELECT *
FROM A
WHERE name = '张三'
AND age > 20;
这类条件的顺序,更多是为了阅读和维护方便。真正决定性能的,还是索引是否匹配、字段基数是否合适,以及 Oracle 最终选出的执行计划。
3. 不要把'语法顺序'误解成'执行顺序'
不少人会把 SQL 理解成'从右到左执行',这其实不准确。SQL 的逻辑处理顺序和物理执行顺序不是一回事,Oracle 会根据成本估算来决定怎么跑。
所以,优化 SQL 时更靠谱的思路是:
- 让过滤条件明确、可用索引
- 避免在条件列上做函数处理
- 尽量减少全表扫描的机会
- 关注执行计划,而不是只看 SQL 写法的表面顺序
关于存储过程
在 SQL Server 里,如果你想把查询封装成一个可重复调用的结果集,存储过程是很常见的做法。虽然这和 Oracle 的 SQL 优化不是一回事,但思路上类似:把常用查询收拢起来,便于维护和复用。
-- 创建一个返回结果集的存储过程(proc 或 procedure 均可)
IF (OBJECT_ID('proc_get_a', 'P') IS NOT NULL)
DROP PROC proc_get_a;
GO
CREATE PROC proc_get_a
AS
BEGIN
SELECT
a;
;
GO
proc_get_a;

