2017-09-17 5 views
0

Ich habe eine große Tabelle (etwa 850 Millionen Zeilen für jetzt) ​​und müssen Perzentilwerte wöchentlich berechnen, wie neue Daten eingefügt wird und die Statik wird schmutzig. Dieser Prozess ist jedoch sehr langsam (5-6 Stunden mit meiner Hardware/aktuellen Abfrage).SQL Perzentil Berechnung läuft sehr langsam - brauche Hilfe Beschleunigung

Wie kann ich meine Abfrage ändern, um die Abfrage zu beschleunigen?

Gerade jetzt, meine Frage ist im Grunde dieses:

SELECT DISTINCT [ident1] 
    ,[ident2] 
    ,[ident3] 
    ,[ident4] 
    ,percentile_cont(0.05) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_5] 
    ,percentile_cont(0.10) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_10] 
    ,percentile_cont(0.25) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_25] 
    ,percentile_cont(0.50) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_50] 
    ,percentile_cont(0.75) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_75] 
    ,percentile_cont(0.90) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_90] 
    ,percentile_cont(0.95) 
     WITHIN GROUP (
      ORDER BY [value] ASC 
     ) OVER (
      PARTITION BY [ident1] 
       ,[ident2] 
       ,[ident3] 
       ,[ident4] 
     ) AS [percentile_95] 
FROM dataTable 

Ich denke , den Teil des Problems ist, dass mit aus der DISTINCT Auswahl Ich bin in der DB jeden Wert einer Reihe zu bekommen. Ist SQL intelligent genug, um die Perzentile nur einmal für jede Gruppe zu berechnen? Oder berechnet es wiederholt für jeden Wert?

Jede Hilfe würde sehr geschätzt werden.

+0

Benötigen Sie Perzentil _ ** cont ** oder ist es in Ordnung, Perzentil _ ** Scheibe ** zu verwenden? – dnoeth

+0

Was sagt ein Ausführungsplan über diese Abfrage? (Der erste zu überprüfende Ort sollte ein Ausführungsplan sein.) Er kann zum Beispiel einen fehlenden Index identifizieren. –

+0

Ich arbeite daran, den Ausführungsplan zu bekommen. Mein DBA hat diese Funktion im Moment deaktiviert. In der Zwischenzeit, was ist der beste Weg, dies zu indexieren? Clustered-Index für [ident1], [ident2], [ident3], [ident4] und [value]? Oder vielleicht eine Teilmenge der Spalten? – hoytdj

Antwort

0

gebe verschiedene in einer Unterabfrage:

select . . . 
from (select distinct . . .) s; 

distinct sollte nach alle select Spalten passiert sein berechnet wurden.

+0

Dies wird den Ausführungsplan nicht ändern, Windowed Aggregates werden * vor * 'distinct' – dnoeth

+0

@dnoeth berechnet. . . Genau. Wenn es 100 Kopien einer gegebenen Reihe gibt, werden sie 100 mal berechnet. Vermutlich möchte das OP die Fensterfunktionswerte, nachdem das Unterscheidungsmerkmal angewendet wurde. –

+1

Aber ein Perzentil wird normalerweise für den gesamten Datensatz berechnet. Wenn Sie DISTINCT vorher anwenden, kann sich das Ergebnis ändern. – dnoeth