【发布时间】:2019-07-22 08:28:29
【问题描述】:
我有一个使用相关子查询的 Oracle SQL 查询:
Q1 P>
SELECT t1.id,
t3.code,
t3.processed_date,
(t1.total / t2.rate)
FROM table1 t1
JOIN table2 t2 ON t2.code= t1.code
JOIN table3 t3 ON t3.id = t1.id
JOIN table4 t4 ON t4.code = t1.code
AND t4.type IN ('value1', 'value2', 'value3')
AND t3.processed_date >= '01 JUL 2019'
AND t3.processed_date < '22 JUL 2019'
AND t2.effective_date IN (SELECT max(tc.effective_date)
FROM tableCore tc
WHERE tc.effective_date <= t3.processed_date
AND t1.code = tc.code)
我已将子查询更改为 Empty OVER() 原因,这显着提高了此查询的性能:
Q2 P>
SELECT t1.id,
t3.code,
t3.processed_date,
(t1.total / t2.rate)
FROM table1 t1
JOIN table2 t2 ON t2.code= t1.code
JOIN table3 t3 ON t3.id = t1.id
JOIN table4 t4 ON t4.code = t1.code
AND t4.type IN ('value1', 'value2', 'value3')
AND t3.processed_date >= '01 JUL 2019'
AND t3.processed_date < '22 JUL 2019'
AND t2.effective_date IN (SELECT max(tc.effective_date) OVER () AS ed
FROM tableCore tc
WHERE tc.effective_date <= t3.processed_date
AND t1.code = tc.code)
新查询返回与原始查询相同的结果集,因此似乎正在运行...,但是为什么解释计划如此不同,它似乎仍然相关,它不是对外部查询了吗?为什么?
我想了解第二个查询中发生了什么。
我想我可以使用row_number() OVER (partition by ...) 以第三种方式重写此查询:
Q3 P>
SELECT t1.id,
t3.code,
t3.processed_date,
(t1.total / t2.rate),
ct.*
FROM table1 t1
JOIN table2 t2 ON t2.code = t1.code
JOIN table3 t3 ON t3.id = t1.id
JOIN table4 t4 ON t4.code = t1.code
JOIN (SELECT ct.*, row_number() OVER (PARTITION BY ct.code ORDER BY ct.effective_date ASC) AS rn
FROM tablecore ct) ct
ON t1.code = ct.code
AND rn = 1
AND ct.effective_date <= t3.processed_date
WHERE t2.effective_date in(ct.effective_date)
AND t4.type IN ('value1', 'value2', 'value3')
AND t3.processed_date >= '01 JUL 2019'
AND t3.processed_date < '22 JUL 2019'
AND t2.effective_date IN (ct.effective_date);
这个版本似乎也可以,但是比第二个版本慢。
编辑 正如@Christian Q3 指出的那样,将返回不正确的结果
【问题讨论】:
-
你能提供两个查询的执行计划吗?
标签: sql oracle correlated-subquery analytic-functions