SQL 优化:使用不同的 where 子句查询 table
SQL Optimization: query table with different where clauses
我有以下 SQL 查询:
SELECT (
SELECT SUM(c1)
FROM t2
WHERE t1.c1 = t2.c1
AND t2.c3 = 'NEW'
AND t2.c4 = TRUNC(SYSDATE)
AND t2.c5 = 'N'
) SUM,
(
SELECT sum(c2)
FROM t2
WHERE t1.c1 = t2.c1
AND t2.c3 = 'OLD'
AND t2.c4 = TRUNC(SYSDATE)
) SUM2
FROM t1
WHERE t1.c2 IN ('DUMMY', 'DUMMY2')
因此,t2
table 被多次查询,但每次都有不同的 WHERE
子句。这个 t2
table 非常大,所以需要一些时间才能得到结果。最好只使用所有不同的 WHERE
子句和 SUM
结果查询此 table 一次..
这有可能吗?我得到了在 SQL 中使用 WITH AS 的建议,但我的执行时间没有成功
你可以试试这个:
SELECT SUM1.val, SUM2.val
FROM (SELECT * FROM t1 WHERE t1.c2 IN ('DUMMY', 'DUMMY2')) as t1
INNER JOIN (
SELECT SUM(c1) as val
FROM t2
WHERE t2.c3 = 'NEW'
AND t2.c4 = TRUNC(SYSDATE)
AND t2.c5 = 'N'
) SUM1
ON t1.c1 = SUM1.c1
INNER JOIN (
SELECT SUM(c2) as val
FROM t2
WHERE t2.c3 = 'OLD'
AND t2.c4 = TRUNC(SYSDATE)
) SUM2
ON t1.c1 = SUM2.c1
您可以对 t2
中的 case
表达式进行多次 sum
调用,然后将其加入 t1
:
SELECT sum1, sum2
FROM t1
JOIN (SELECT c1,
SUM(CASE WHEN c3 = 'NEW' AND
c4 = TRUNC(SYSDATE) AND
c5 = 'N' THEN c1
ELSE NULL END) AS sum1,
SUM(CASE WHEN c3 = 'OLD' AND
c4 = TRUNC(SYSDATE) THEN c2
ELSE NULL END) AS sum2
FROM t2) t2 ON t1.c1 = t2.c1
WHERE t1.c2 IN ('DUMMY', 'DUMMY2')
编辑:case
表达式(即 c4 = TRUNC(SYSDATE)
)中的常见条件可以提取到 where
子句,这应该会提供一些性能增益:
SELECT sum1, sum2
FROM t1
JOIN (SELECT c1,
SUM(CASE WHEN c3 = 'NEW' AND c5 = 'N' THEN c1
ELSE NULL END) AS sum1,
SUM(CASE WHEN c3 = 'OLD' THEN c2
ELSE NULL END) AS sum2
FROM t2
WHERE c4 = TRUNC(SYSDATE)) t2 ON t1.c1 = t2.c1
WHERE t1.c2 IN ('DUMMY', 'DUMMY2')
这个查询给了我与你原来的 SQL 相同的结果,样本数据:
with
a as (select c1 from t1 where c2 in ('DUMMY', 'DUMMY2')),
b as (
select c1,
sum (case when c3 = 'NEW' and c5 = 'N' then c1 end) sum1,
sum (case when c3 = 'OLD' then c2 end) sum2
from t2
where c4 = trunc(sysdate) and exists (select 1 from a where c1 = t2.c1)
group by c1
)
select * from a left join b using (c1)
...而且应该更快,因为我试图将它限制在必要的步骤内。
如果列 c1
在 table t1
中是唯一的,那么查询可能会被简化,但我在这里没有假设唯一性。
顺便说一句 - 您确定 sum1
是对 c1
列求和,而不是 c2
?
我有以下 SQL 查询:
SELECT (
SELECT SUM(c1)
FROM t2
WHERE t1.c1 = t2.c1
AND t2.c3 = 'NEW'
AND t2.c4 = TRUNC(SYSDATE)
AND t2.c5 = 'N'
) SUM,
(
SELECT sum(c2)
FROM t2
WHERE t1.c1 = t2.c1
AND t2.c3 = 'OLD'
AND t2.c4 = TRUNC(SYSDATE)
) SUM2
FROM t1
WHERE t1.c2 IN ('DUMMY', 'DUMMY2')
因此,t2
table 被多次查询,但每次都有不同的 WHERE
子句。这个 t2
table 非常大,所以需要一些时间才能得到结果。最好只使用所有不同的 WHERE
子句和 SUM
结果查询此 table 一次..
这有可能吗?我得到了在 SQL 中使用 WITH AS 的建议,但我的执行时间没有成功
你可以试试这个:
SELECT SUM1.val, SUM2.val
FROM (SELECT * FROM t1 WHERE t1.c2 IN ('DUMMY', 'DUMMY2')) as t1
INNER JOIN (
SELECT SUM(c1) as val
FROM t2
WHERE t2.c3 = 'NEW'
AND t2.c4 = TRUNC(SYSDATE)
AND t2.c5 = 'N'
) SUM1
ON t1.c1 = SUM1.c1
INNER JOIN (
SELECT SUM(c2) as val
FROM t2
WHERE t2.c3 = 'OLD'
AND t2.c4 = TRUNC(SYSDATE)
) SUM2
ON t1.c1 = SUM2.c1
您可以对 t2
中的 case
表达式进行多次 sum
调用,然后将其加入 t1
:
SELECT sum1, sum2
FROM t1
JOIN (SELECT c1,
SUM(CASE WHEN c3 = 'NEW' AND
c4 = TRUNC(SYSDATE) AND
c5 = 'N' THEN c1
ELSE NULL END) AS sum1,
SUM(CASE WHEN c3 = 'OLD' AND
c4 = TRUNC(SYSDATE) THEN c2
ELSE NULL END) AS sum2
FROM t2) t2 ON t1.c1 = t2.c1
WHERE t1.c2 IN ('DUMMY', 'DUMMY2')
编辑:case
表达式(即 c4 = TRUNC(SYSDATE)
)中的常见条件可以提取到 where
子句,这应该会提供一些性能增益:
SELECT sum1, sum2
FROM t1
JOIN (SELECT c1,
SUM(CASE WHEN c3 = 'NEW' AND c5 = 'N' THEN c1
ELSE NULL END) AS sum1,
SUM(CASE WHEN c3 = 'OLD' THEN c2
ELSE NULL END) AS sum2
FROM t2
WHERE c4 = TRUNC(SYSDATE)) t2 ON t1.c1 = t2.c1
WHERE t1.c2 IN ('DUMMY', 'DUMMY2')
这个查询给了我与你原来的 SQL 相同的结果,样本数据:
with
a as (select c1 from t1 where c2 in ('DUMMY', 'DUMMY2')),
b as (
select c1,
sum (case when c3 = 'NEW' and c5 = 'N' then c1 end) sum1,
sum (case when c3 = 'OLD' then c2 end) sum2
from t2
where c4 = trunc(sysdate) and exists (select 1 from a where c1 = t2.c1)
group by c1
)
select * from a left join b using (c1)
...而且应该更快,因为我试图将它限制在必要的步骤内。
如果列 c1
在 table t1
中是唯一的,那么查询可能会被简化,但我在这里没有假设唯一性。
顺便说一句 - 您确定 sum1
是对 c1
列求和,而不是 c2
?