Можем ли мы использовать функцию разбиения по окнам для запроса ниже - PullRequest
0 голосов
/ 19 марта 2019

У меня есть запрос, как показано ниже. Могу ли я использовать разделение по оконной функции вместо группировки по и объединения? Я должен изменить имя партнера и номер партнера. Также в зависимости от партнера номер один из групп по полю меняется. мой соблазн содержит около 24 миллионов записей. Я работаю над улучшением производительности этого запроса. в настоящее время моя хранимая процедура занимает около 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]   

Пожалуйста, дайте свое предложение улучшить производительность этого запроса.

1 Ответ

0 голосов
/ 19 марта 2019

Я упрощаю запрос. У вас есть такие данные:

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 означает F7 для партнера -2 и F9 для партнера -3). Из пяти строк в таблице вы получите шесть строк результата, несмотря на агрегацию. Таким образом, подход, который вы уже предприняли, чтобы объединить два запроса, уже является единственным возможным подходом. Я полагаю, что ваше предложение where (WHERE [Partner #] > 0) не исключает очень много строк, поэтому большая часть данных таблицы должна быть прочитана и отсортирована, а затем сгруппирована для агрегирования. И это должно случиться даже дважды. Это требует времени. Вы ничего не можете с этим поделать. Моя первая идея - купить оборудование.

Вы можете использовать следующие индексы для предоставления предварительно отсортированных данных. Это предложение для СУБД, которое оно может или не может принять для запроса.

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...