我有一个类似的查询:
(q1)
select a,b,c,d from abc
where param='x'
union
(q2)
select e,f,g,h from abc
where param='y'
我想知道<param>='y'
的值是否会被query1执行?
这是因为recodset“abc”非常大,实际查询涉及相同参数的5-6个联合(你可能会看到一次只需要一个查询数据)。因此,如果从所有查询中获取数据并根据where子句进行过滤,那么这将是一个很大的开销,而如果之前进行过滤,那么实际上只有五分之一的查询被执行。
由于 人士Himanshu
答案 0 :(得分:2)
如果你写的话
where 1 = 2
可以在不触及数据库的情况下进行评估,然后Oracle会非常聪明地跳过访问表格。
这应该适用于绑定变量。
where ? = ?
当然,只要涉及到列,就必须查看数据。
答案 1 :(得分:2)
如果'param'是abc中的一列,那么在索引该列时会有很大帮助。
但是查询中最大的性能影响可能是“联合”,因为Oracle必须过滤掉重复的行。根据结果集的大小,这是一个非常繁重的操作(排序,删除重复项)。如果你不关心重复的结果(或者由于查询的定义它们根本不可能),请使用'union all':
select a,b,c,d from abc
union all
select e,f,g,h from abc
答案 2 :(得分:2)
select *
from (
select 1 INDICATOR,
a, b, c
from abc
union all
select 2 INDICATOR,
a, b, c
from abc)
where indicator = 1;
这不会在union中执行第二个查询。正如您在执行计划中所看到的,有一个过滤器,表示“null不为空”。然而,许多工会存在巨大的开销。
答案 3 :(得分:1)
在我看来,这是懒惰的编程,你正试图让数据库完成应用程序的工作。
是一个带有大量连接的简单“if”语句答案 4 :(得分:0)
问题告诉我,您要避免对数据集进行两次全表扫描。 这项技术可能可以帮助您。
WITH
base AS
(
SELECT a,b,c,d,e,f,g,h FROM abc -- all columns of interest
WHERE param IN ('x', 'y') -- all rows of interest
),
q1 AS
(
select a,b,c,d from base -- one specific subset
where param='x'
),
q2 AS
(
select e,f,g,h from base -- the other specific subset
where param='y'
)
SELECT a,b,c,d FROM abc -- then the union of the sets
UNION
SELECT e,f,g,h FROM abc -- that you are interested in.
当您在param上进行查找时,索引将具有很大的价值,允许使用成本较低的INDEX扫描替换FULL TABLE SCAN。
如果param中的一组不同值很小,那么构建histograms可能会有好处。
与甲骨文一样,您的里程可能会有所不同。
我很想知道这一切是怎么回事。
答案 5 :(得分:0)
正如其他人所指出的,Oracle将在评估绑定变量后从查询中删除死代码分支。您可以用“union all”替换union,(不管它是否应该重要),但开发人员的意图更清楚(我,开发人员预计此处不会重复)。
一个悬而未决的问题(无论如何)是:你能确定“a”的数据类型与“e”和“b”匹配“f”等等吗?
实际上,我自己从未实现过,只读过它,所以有人想验证我在说什么。但是一种完全不同的方法可能是创建一个接受参数的存储过程。 该过程将为每个预期的param值提供一个游标。然后你可以测试(IF)参数的值并返回一个引用光标。