我有一个如下查询。我可以使用分区窗口功能而不是分组和联合吗?我必须更改合作伙伴名称和合作伙伴编号。同样基于合作伙伴编号的一个字段正在改变。我的临时表包含大约2400万条记录。我正在努力提高此查询的性能。目前我的存储过程需要大约1小时才能执行。
INSERT INTO #FinalResultTable
(
[F1],
[F2],
[F3],
[F4],
[Partner #],
[Partner Name],
[F5],
[F6],
[F7],
[F8],
[Partner Amount (rounded)]
,[Entity Name]
,[Investment Number]
)
SELECT
[F1],
[F2],
[F3],
[F4],
-2 as [Partner #],
'Work Paper Total'
AS [PartnerName], -- VARCHAR
[F5],
[F6],
[F7],
[F8],
MAX([WorkPaperTotal])
, [Entity Name]
,[Investment Number]
FROM #FinalResultTable
WHERE [Partner #] > 0
GROUP BY
[F1],
[F2],
[F3],
[F4],
[F5],
[F6],
[F7],
[F8],
[Entity Name],
[Investment Number]
union all
SELECT
[F1],
[F2],
[F3],
[F4],
-3 as [Partner #],
'Partner Total'
AS [PartnerName], -- VARCHAR
[F5],
[F6],
[F9],
[F10],
MAX([WorkPaperTotal]) -SUM([Partner Amount (rounded)])
, [Entity Name]
,[Investment Number]
FROM #FinalResultTable
WHERE [Partner #] > 0
GROUP BY
[F1],
[F2],
[F3],
[F4],
[F5],
[F6],
[F9],
[F10],
[Entity Name],
[Investment Number]
请提出您的建议,以提高此查询的性能。
我正在简化请求。你有这样的数据:
F1 | F7 | F9 | WorkPaperTotal | PartnerAmount ---+----+----+----------------+-------------- 1 | 1 | 1 | 1000 | 10 1 | 1 | 2 | 2000 | 20 1 | 2 | 1 | 3000 | 30 1 | 2 | 2 | 4000 | 40 2 | 1 | 1 | 5000 | 50
你想要一个结果
select f1, f7 as f, max(workpapertotal) as result, -2 as partner
from mytable
group by f1, f7
union all
select f1, f9 as f, max(workpapertotal) - sum(partneramount) as result, -3 as partner
from mytable
group by f1, f9;
第一部分为您提供:
F1 | F | result | partner ---+---+--------+-------- 1 | 1 | 2000 | -2 1 | 2 | 4000 | -2 2 | 1 | 5000 | -2
第二部分为您提供:
F1 | F | result | partner ---+---+--------+-------- 1 | 1 | 2960 | -3 1 | 2 | 3940 | -3 2 | 1 | 4950 | -3
这是最终的结果
F1 | F | result | partner ---+---+--------+-------- 1 | 1 | 2000 | -2 1 | 1 | 2960 | -3 1 | 2 | 4000 | -2 1 | 2 | 3940 | -3 2 | 1 | 5000 | -2 2 | 1 | 4950 | -3
(其中F表示伙伴-2的F7和伙伴-3的F9)。从表中的五行开始,无论聚合如何,都会得到六个结果行。因此,您已经采取的两个查询联合的方法已经是唯一可行的方法。我想你的where子句(WHERE [Partner #] > 0
)并没有排除很多行,因此必须读取和排序表的大部分数据然后进行分组才能聚合。这甚至必须发生两次。这需要时间。你无能为力。购买硬件将是我的第一个想法。
您可以尝试以下索引,以便提供预先排序的数据。这是对DBMS的提议,它可能会或可能不会接受查询。
CREATE INDEX idx1
ON #FinalResultTable(f1,f2,f3,f4,f5,f6,f7,f8,[Entity Name],[Investment Number])
WHERE [Partner #] > 0;
CREATE INDEX idx2
ON #FinalResultTable(f1,f2,f3,f4,f5,f6,f9,f10,[Entity Name],[Investment Number])
WHERE [Partner #] > 0;