如何优化此SQL查询?
我在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 所以我提出了这个问题:如何优化此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
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%”转义“\”