2017-09-17 31 views
0

大きなテーブル(現在は約850万行)があり、毎週パーセンタイル値を計算する必要があります。しかし、そのプロセスは非常に遅い(ハードウェア/現在のクエリでは5〜6時間)。SQLパーセンタイルの計算が非常に遅い - 高速化に役立つ

クエリを高速化するためにクエリを変更するにはどうすればよいですか?

は今のところ、私のクエリは、基本的にはこれです:

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 

私は問題の一部である思いそのDISTINCT選択から、私は、行にDB内のすべての値を取得していますと。 SQLは各グループごとに一度だけパーセンタイルを計算するのに十分スマートですか?それとも、それぞれの値に対して繰り返し計算していますか?

ご協力いただければ幸いです。

+0

パーセンタイル_ ** cont **が必要ですか、それともパーセンタイル_ **ディスク**を使用してもよろしいですか? – dnoeth

+0

実行計画はこのクエリについて何を伝えますか? (最初の場所は実行計画でなければなりません)。たとえば、索引が見つからないことがあります。 –

+0

私は実行計画の作成に取り組んでいます。私のDBAはその時点で機能を無効にしています。その間、これをインデックス化する最良の方法は何ですか? [ident1]、[ident2]、[ident3]、[ident4]、および[value]のクラスタード・インデックス?または列の一部のサブセットですか? – hoytdj

答えて

0

サブクエリで明確なを入れて:

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

distinctはすべてselect列が計算された後に起こってしなければなりません。

+0

これは実行計画を変更しません。Windowed Aggregatesは* distinct * before * 'distinct'と計算されます – dnoeth

+0

@dnoeth。 。 。まったく。特定の行のコピーが100個ある場合、それらは100回計算されます。おそらく、OPは、distinctが適用された後にwindowed関数の値を求めます。 –

+1

しかし、パーセンタイルは通常、完全なデータセットで計算されます。DISTINCTを適用すると結果が変わる可能性があります。 – dnoeth

関連する問題