Database 执行where子句的Sql查询

Database 执行where子句的Sql查询,database,oracle,sql,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' 我想知道='y'的值是否会执行query1?? 这是因为记录集“abc”非常大,实际查询涉及同一参数上的5-6个联合(您可能会看到一次只需要一个查询数据)。因此,如果从所有查询中提取数据,并根据where子句进行过滤,那么这将是一个巨大的开销,而如果在之前进行过滤,那么实际上

我有一个类似这样的问题:

(q1)
select a,b,c,d from abc
where param='x'

union

(q2)
select e,f,g,h from abc
where param='y'
我想知道
='y'
的值是否会执行query1?? 这是因为记录集“abc”非常大,实际查询涉及同一参数上的5-6个联合(您可能会看到一次只需要一个查询数据)。因此,如果从所有查询中提取数据,并根据where子句进行过滤,那么这将是一个巨大的开销,而如果在之前进行过滤,那么实际上只执行五分之一的查询

谢谢
希曼书

如果你写的是

where 1 = 2
这可以在不接触数据库的情况下进行评估,那么Oracle将足够聪明,可以跳过对表的访问

这甚至可以用于绑定变量

where ? = ?

当然,一旦涉及到列,它就必须查看数据。

如果您编写类似

where 1 = 2
这可以在不接触数据库的情况下进行评估,那么Oracle将足够聪明,可以跳过对表的访问

这甚至可以用于绑定变量

where ? = ?

当然,一旦涉及到列,它就必须查看数据。

如果“param”是abc中的一个列,那么在为该列编制索引时会有很大帮助

但是查询中最大的性能影响可能是“联合”,因为Oracle必须过滤掉重复的行。根据结果集的大小,这是一个相当繁重的操作(排序、删除重复项)。如果您不关心重复的结果(或者由于查询的定义,它们根本不可能),请使用“union all”:

select a,b,c,d from abc
union all
select e,f,g,h from abc

如果“param”是abc中的一列,那么在为该列编制索引时,它将非常有用

但是查询中最大的性能影响可能是“联合”,因为Oracle必须过滤掉重复的行。根据结果集的大小,这是一个相当繁重的操作(排序、删除重复项)。如果您不关心重复的结果(或者由于查询的定义,它们根本不可能),请使用“union all”:

select a,b,c,d from abc
union all
select e,f,g,h from abc

在我看来,这是一种懒惰的编程,您正试图让数据库完成应用程序的工作。您只需要一个简单的“if”语句和一系列连接就可以了。

在我看来,这是一个懒惰的编程,您正试图让数据库完成应用程序的工作。您只需要一个简单的“if”语句和一系列串联

select *
from (
select 1 INDICATOR,
       a, b, c
from abc
union all
select 2 INDICATOR,
       a, b, c
from abc)
where indicator = 1;
这不会在联合中执行第二个查询。正如您在执行计划中所看到的,有一个过滤器,它说“null不是null”。然而,许多工会都有很大的开销


这不会在联合中执行第二个查询。正如您在执行计划中所看到的,有一个过滤器,它说“null不是null”。但是,许多联合会有很大的开销。

这个问题向我建议,您要避免对数据集进行两次完整的表扫描。 这项技巧可能会对你有所帮助

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时,索引具有很大的价值,可以用成本较低的索引扫描代替完整的表扫描

如果param中的一组不同的值很小,则可能有利于构建

与Oracle的所有情况一样,您的里程数可能会有所不同


我很想听听这一切对您的影响。

这个问题向我建议,您希望避免对数据集进行两次完整的表扫描。 这项技巧可能会对你有所帮助

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时,索引具有很大的价值,可以用成本较低的索引扫描代替完整的表扫描

如果param中的一组不同的值很小,则可能有利于构建

与Oracle的所有情况一样,您的里程数可能会有所不同


我很想听听这一切对您的影响。

正如其他人所指出的,Oracle将在对bind变量求值后从您的查询中删除死代码分支。您可以将union替换为“union all”(无论如何,这并不重要),但开发人员的意图会更清楚地显示出来(即,开发人员希望这里没有重复)

一个悬而未决的问题(无论如何对我来说)是:你能肯定地知道“a”的数据类型匹配“e”和“b”匹配“f”等等吗

实际上,我自己从来没有实现过这一点,只是为了让别人相信我说的话。但另一种完全不同的方法可能是创建一个接受参数的存储过程。
对于param的每个预期值,该过程将有一个游标。然后,您可以测试(如果)param的值并返回一个ref游标。

正如其他人所指出的,Oracle将在计算完bind变量后从查询中删除死代码分支。您可以将union替换为“union all”(无论如何,这并不重要),但开发人员的意图会更清楚地显示出来(即,开发人员希望这里没有重复)

一个悬而未决的问题(无论如何对我来说)是:你能肯定地知道“a”的数据类型匹配“e”和“b”匹配“f”等等吗

实际上,我自己从来没有实现过这一点,只是为了让别人相信我说的话。但另一种完全不同的方法可能是创建一个接受参数的存储过程。
对于param的每个预期值,该过程将有一个游标。然后,您可以测试(如果)参数的值并返回一个ref游标。

此外,我正在使用Oracle DB(影响答案的id)尝试阅读更多关于基本SQL概念的内容;同时,对于每个SQL,您可以发出解释。。。RDBMS将向您展示一个计划(这将需要您学习更多的概念,但从长远来看,如果您想了解SQL与实际数据访问路径和算法之间的细微差别,这将非常有用)。这一个清除了绑定变量,而且我使用的是ORACLEDB(影响答案的id)T