我们可以使用分区窗函数进行下面的查询

问题描述 投票:0回答:1

我有一个如下查询。我可以使用分区窗口功能而不是分组和联合吗?我必须更改合作伙伴名称和合作伙伴编号。同样基于合作伙伴编号的一个字段正在改变。我的临时表包含大约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]   

请提出您的建议,以提高此查询的性能。

sql sql-server database-performance
1个回答
0
投票

我正在简化请求。你有这样的数据:

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;
© www.soinside.com 2019 - 2024. All rights reserved.