用where子句执行的SQL查询

时间:2010-11-19 10:49:56

标签: database oracle sql

我有一个类似的查询:

(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

6 个答案:

答案 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)参数的值并返回一个引用光标。