我有一个非常复杂的查询,该查询基于联合在一起的多个表。目前,我们正在使用 View 来对我们需要的所有行执行操作,因此 View 和查询如下所示:
CREATE VIEW
V_VIEW
(
COL1, COL2, COL3, COL4
) AS
SELECT
"COL1", "COL2", "COL3", "COL4"
FROM
TABLE1
UNION ALL
SELECT
"COL1", "COL2", "COL3", "COL4"
FROM
TABLE2;
SELECT
COL1, COL2
FROM
( SELECT
COL1, COL2
FROM
V_VIEW
WHERE
COL1 like 'val%'
AND COL2 =
(
SELECT
MAX(COL3)
FROM
V_VIEW
WHERE
COL4 = 'Y' ) part1
UNION ALL
SELECT
COL1, COL2
FROM
( SELECT
COL1, COL2
FROM
V_VIEW
WHERE
COL1 like 'sth%'
AND COL2 =
(
SELECT
MIN(COL3)
FROM
V_VIEW
WHERE
COL4 = 'N' ) part2;
我正在寻找一种方法来提高此查询的性能,不幸的是,目前无法创建包含 Table1 和 Table2 的所有行的新表(我们不允许干扰在那里插入行的方式)。我尝试使用WITH子句而不是 View ,所以它看起来有点像:
WITH TEMP_TABLE AS (
SELECT
COL1, COL2, COL3, COL4
FROM
TABLE1
UNION ALL
SELECT
COL1, COL2, COL3, COL4
FROM
TABLE2 )
SELECT
COL1, COL2
FROM
( SELECT
COL1, COL2
FROM
TEMP_TABLE
WHERE
COL1 like 'val%'
AND COL2 =
(
SELECT
MAX(COL3)
FROM
TEMP_TABLE
WHERE
COL4 = 'Y' ) part1
UNION ALL
SELECT
COL1, COL2
FROM
( SELECT
COL1, COL2
FROM
TEMP_TABLE
WHERE
COL1 like 'sth%'
AND COL2 =
(
SELECT
MIN(COL3)
FROM
TEMP_TABLE
WHERE
COL4 = 'N' ) part2
对于小数据量(Table1 和 Table2 大约有 20k 行),这可以很好地提高性能。然而,这些表最终将塞满数百万行。我不完全理解WITH子句是如何处理的,所以我想知道:在大量数据上使用WITH闭包的查询是否有可能失败(由于内存不足?),而没有它的查询工作会很慢,但是会很好地完成吗?
最佳答案
您可以尝试使用以下方法:
WITH main_res AS (SELECT col1,
col2,
MAX(CASE WHEN col4 = 'N' THEN col3) OVER () col3_n_max,
MAX(CASE WHEN col4 = 'Y' THEN col3) OVER () col3_y_max
FROM v_view
WHERE col1 LIKE 'val%'
OR col1 LIKE 'sth%')
SELECT col1,
col2
FROM main_res
WHERE (col1 LIKE 'val%' AND col2 = col3_y_max)
OR (col1 LIKE 'sth%' AND col2 = col3_n_max);
这使用条件最大值分析函数返回所有行的最大值(取决于 col4 值)。
了解该信息后,您就可以对其进行适当的过滤。这应该会减少查询每个表的次数,这通常比原始查询更快(但并非总是如此!)。我建议您在选择使用哪个查询之前测试此查询并确定它是否比原始查询(以及任何其他答案)更快。
关于sql - Oracle WITH 子句限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56422995/