【发布时间】:2020-08-12 11:12:03
【问题描述】:
最近我遇到了一种我无法解释的奇怪行为,需要一些帮助来理解为什么会这样。
想象以下场景:我想检索在用户无权访问的所有房间中发生的所有类。为此,我在如下查询中使用not in:
select id
from class
where room_id not in
(
select room_id
from user_room
where user_id = 123
)
虽然我认为因为内部查询(在not in 内)独立于外部查询(非相关查询),所以内部查询只会执行一次,但发生的情况是它每次执行一次记录在类表中。这会对性能造成很大影响。
我之所以说它对每个类记录执行一次是因为查询的解释计划,如下所示:
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 59 | 144 (0)| 00:00:01 |
| 1 | NESTED LOOPS ANTI | | 1 | 59 | 144 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| CLASS | 137 | 6302 | 144 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN| USER_ROOM_UK | 4 | 52 | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
我假设 ID 为 1 的步骤是针对表类的每条记录执行的 not in 查询。我的解释正确吗?
如果我用查询返回的值替换 not in 查询,类似于:
select id
from class
where room_id not in
(
1, 2, 3
)
解释计划现在显示:
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 125 | 5750 | 144 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| CLASS | 125 | 5750 | 144 (0)| 00:00:01 |
---------------------------------------------------------------------------
这就是为什么我假设每个外部查询记录都执行一次内部查询。
我想了解为什么会这样。它不应该只执行一次,因为我正在处理不相关的查询吗?还是我的任何假设是错误的?
另外,有没有办法告诉 Oracle 引擎只执行一次内部查询?
感谢任何反馈! 谢谢!
【问题讨论】:
-
您在此处标记了 2 个完全不同的 RDBMS。您实际使用的是哪个?
-
@Larnu 对不起,很糟糕。感谢您的提醒!
标签: query-performance oracle19c