我有这样的东西:
With a as (select id from table_a)
select * from table_b where table_b.id > (select min(id) from a)
table_a是一个巨大的表,具有数百万条记录,我不想每次使用min(i)时都要遍历所有记录来查找min(i)。有什么办法可以将min(id)存储在变量中并在查询中使用它?像这样:
With a as (select id from table_a),
b as ((select min(id) into min_id from a))
select * from table_b where table_b.id > min_id
答案 0 :(得分:0)
您的查询应该在做您想要的。但是,如果您确实希望确定,请将子查询移至from
子句:
select b.*
from table_b b join
(select min(id) as min_id from a) a
on b.id > a.min_id;
答案 1 :(得分:0)
您可以通过在列table_a
上的id
上定义索引来帮助Oracle,而不用遍历所有记录来查找最小值。
如果定义了索引,Oracle将执行一次索引访问以获取最小行。
没有索引,您将执行大表的FULL TABLE SCAN
个。
验证的最佳方法是遵守执行计划:
create index idx_a on table_a(id);
EXPLAIN PLAN SET STATEMENT_ID = 'q1' into plan_table FOR
With a as (select id from table_a)
select * from table_b
where table_b.id > (select min(id) from a);
SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table', 'q1','ALL'));
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5524 | 71812 | 49 (3)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | TABLE_B | 5524 | 71812 | 47 (3)| 00:00:01 |
| 2 | SORT AGGREGATE | | 1 | 13 | | |
| 3 | INDEX FULL SCAN (MIN/MAX)| IDX_A | 1 | 13 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("TABLE_B"."ID"> (SELECT MIN("ID") FROM "TABLE_A" "TABLE_A"))