如何优化此SQL查询?

如何优化此SQL查询?,sql,oracle,query-optimization,Sql,Oracle,Query Optimization,我在Oracle上下文中有3个表,我们称它们为t1、t2、t3,它们具有以下结构: t1:t1\U ID,t1\U名称。。。 t2:t1\U ID,t3\U名称。。。 t3:t3_名称,randomCol1,randomCol2,randomCol3。。。 我想要的是一个查询,它会给出如下结果: t0|u name|randomCol 所以我提出了这个问题: SELECT t1.t1_name, t3.randomCol1 AS randomCol FROM t1

我在Oracle上下文中有3个表,我们称它们为t1、t2、t3,它们具有以下结构:

t1:t1\U ID,t1\U名称。。。 t2:t1\U ID,t3\U名称。。。 t3:t3_名称,randomCol1,randomCol2,randomCol3。。。 我想要的是一个查询,它会给出如下结果:

t0|u name|randomCol

所以我提出了这个问题:

      SELECT t1.t1_name, t3.randomCol1 AS randomCol
      FROM t1
      JOIN t2 ON t1.t1_ID=t2.t1_ID
      JOIN t3 ON t2.t3_name=t3.t3_name
      WHERE t3.randomCol1 LIKE '_%'
    UNION
      SELECT t1.t1_name, t3.randomCol2 AS randomCol
      FROM t1
      JOIN t2 ON t1.t1_ID=t2.t1_ID
      JOIN t3 ON t2.t3_name=t3.t3_name
      WHERE t3.randomCol2 LIKE '_%'
    UNION
      SELECT t1.t1_name, t3.randomCol3 AS randomCol
      FROM t1
      JOIN t2 ON t1.t1_ID=t2.t1_ID
      JOIN t3 ON t2.t3_name=t3.t3_name
      WHERE t3.randomCol3 LIKE '_%'
因为我希望所有以u开头的randomCols值都在一个列中,并与链接到它们的t1_名称配对。 为了提供更多信息,randomCol1和randomCol2几乎相同,它们在同一时间不为null,并且具有几乎相同的值,而randomCol3通常为null

我知道这在性能上很糟糕,所以我试着改进它

因此,我在网上搜索了各种方法来优化这个解决方案,比如使用UNION ALL和stuff,但没有找到我想要的确切结果

因此,我的问题如下: 你知道我如何优化这个查询吗


关于

在SQL Server中

SELECT t0_name, randomCol
FROM (SELECT t0_name, randomCol1, randomCol2, etc)
      FROM t0
      JOIN t01 ON t0.t0_ID=t1.t0_ID
      JOIN t1 ON t01.t1_name=t1.t1_name) p
UNPIVOT (randomCol FOR items in (randomCol1, randomCol2, etc)) unpvt
WHERE randomCol like '_%'

我认为在Oracle中也是一样的:请参见SQL Server中的

SELECT t0_name, randomCol
FROM (SELECT t0_name, randomCol1, randomCol2, etc)
      FROM t0
      JOIN t01 ON t0.t0_ID=t1.t0_ID
      JOIN t1 ON t01.t1_name=t1.t1_name) p
UNPIVOT (randomCol FOR items in (randomCol1, randomCol2, etc)) unpvt
WHERE randomCol like '_%'
我认为在Oracle中也是如此:请参见

当您执行union或union all时,Oracle可能会多次执行子查询。您可以使用unpivot或使用交叉连接修复此问题,如下所示:

SELECT t1.t1_name,
       (case when n.n = 1 then t3.randomCol1
             when n.n = 2 then t3.randomCol2
             when n.n = 3 then t3.randomCol3
        end) AS randomCol
FROM t1 JOIN
     t2
     ON t1.t1_ID=t2.t1_ID JOIN
     t3
     ON t2.t3_name=t3.t3_name cross join
     (select 1 as n from dual union all select 2 from dual union all select 3) n
where n.n = 1 and LEFT(t3.randomCol1, 1) = '_' or
      n.n = 2 and LEFT(t3.randomCol2, 1) = '_' or
      n.n = 3 and LEFT(t3.randomCol3, 1) = '_'
我将like替换为left,因为“u”是like的wilcard。

执行union或union all时,Oracle可能会多次执行子查询。您可以使用unpivot或使用交叉连接修复此问题,如下所示:

SELECT t1.t1_name,
       (case when n.n = 1 then t3.randomCol1
             when n.n = 2 then t3.randomCol2
             when n.n = 3 then t3.randomCol3
        end) AS randomCol
FROM t1 JOIN
     t2
     ON t1.t1_ID=t2.t1_ID JOIN
     t3
     ON t2.t3_name=t3.t3_name cross join
     (select 1 as n from dual union all select 2 from dual union all select 3) n
where n.n = 1 and LEFT(t3.randomCol1, 1) = '_' or
      n.n = 2 and LEFT(t3.randomCol2, 1) = '_' or
      n.n = 3 and LEFT(t3.randomCol3, 1) = '_'
我将like替换为left,因为“u”是like的wilcard。

一个可能的变体:

  select * from
  (SELECT t1.t1_name, 
          case l.l
              when 1 then t3.randomCol1 
              when 2 then t3.randomCol2 
              when 3 then t3.randomCol3
          end AS randomCol
   FROM (select level l from dual connect by level <= 3) l
   CROSS JOIN t1
   JOIN t2 ON t1.t1_ID=t2.t1_ID
   JOIN t3 ON t2.t3_name=t3.t3_name
   WHERE '_' in (substr(t3.randomCol1,1,1),
                 substr(t3.randomCol2,1,1),
                 substr(t3.randomCol3,1,1))
  ) where randomCol like '_%'
一种可能的变体:

  select * from
  (SELECT t1.t1_name, 
          case l.l
              when 1 then t3.randomCol1 
              when 2 then t3.randomCol2 
              when 3 then t3.randomCol3
          end AS randomCol
   FROM (select level l from dual connect by level <= 3) l
   CROSS JOIN t1
   JOIN t2 ON t1.t1_ID=t2.t1_ID
   JOIN t3 ON t2.t3_name=t3.t3_name
   WHERE '_' in (substr(t3.randomCol1,1,1),
                 substr(t3.randomCol2,1,1),
                 substr(t3.randomCol3,1,1))
  ) where randomCol like '_%'

我们真的必须调用表t0、t01、t1吗?不,为了隐私,我更改了原始名称,但如果您有更好的命名想法,我很乐意采用它:我认为您需要使用UNPIVOT,我将看看是否可以为其提供SQL。请看,您确实需要对代码进行脱敏处理,但是像t1、t2、t3这样的代码更容易阅读。@JulienGanis,顺便问一下,您的查询真的适合您吗?因为“uu”应该是转义的,类似这样的-t3.randomCol1像“\\\u1%”转义“\'我们真的需要调用表t0、t01、t1吗?不,为了隐私,我更改了原始名称,但是如果您有更好的命名想法,我很乐意采用它:我认为您需要使用UNPIVOT,我会看看是否能为它想出SQL。请看,您确实需要对代码进行脱敏处理,但是像t1、t2、t3这样的代码更容易阅读。@JulienGanis,顺便问一下,您的查询真的适合您吗?因为u应该是转义的,类似这样的-其中t3.randomCol1类似于“\u%”转义“\”