【发布时间】:2013-06-06 23:36:30
【问题描述】:
我需要在 Oracle 11G 中执行如下所示的选择:
select distinct p_date, column1, column2, ...
from table1 t1, table2 t2, ...
where (some join relations)
and t1.p_date > to_date('010113','ddmmrr')
在某些时候,我意识到 p_date 上的文件管理器使查询非常慢,而没有 p_date 过滤器的相同查询几乎是立即的。 最重要的是,我意识到没有过滤器的查询返回了一小部分结果,大约 30 行,所以我考虑将日期过滤器移到查询之外。
我尝试了这两个选项:
with temp as (
select distinct p_date, column1, column2, ...
from table1 t1, table2 t2, ...
where (some join relations)
) select * from temp where p_date > to_date('010113','ddmmrr')
和
select * from (
select distinct p_date, column1, column2, ...
from table1 t1, table2 t2, ...
where (some join relations)
) where p_date > to_date('010113','ddmmrr')
期望它几乎和内部查询一样快,因为它应该首先执行它,然后只对返回的 30 行应用 p_date 过滤器。
但是,在这两种情况下,执行时间都很长(我不知道有多少,因为我没有足够的耐心等待结果出来)。
谁能告诉我为什么会这样?
附带说明:表“table1”在 p_date 上有一个索引,看起来不像预期的那样工作(我也在处理这个问题)。但是,Oracle 引擎是否会识别出这一点并在运行时错误地重新设计查询以尝试使用它?
提前致谢,
卡尔斯
【问题讨论】:
-
请发布执行计划。
-
请同时发布表之间的确切连接、Oracle 版本号和表定义
-
如果 Oracle 优化器认为将数据谓词推送到子选择中会更快,它可以重写查询,是的。您需要跟踪它以确切了解它在做什么,但执行计划应该告诉您它仍在使用
p_date索引(可能,根据您的描述)。有一些提示可以避免这种情况,但在尝试这些提示之前,您需要了解为什么会发生这种情况。 -
它从来都不是“几乎立即”,当您在没有过滤器的情况下运行时,它很有可能会从缓冲区缓存中提取大部分块(来自上次运行的查询)。