2017-09-07 7 views
2

私はxとyの2つのテーブルを持っていますこのアップデートをスピードアップして設定するにはどうすればよいですか?

x.col_pが特定の日付とIDに一致する列y.col_pの合計で更新するクエリを作成しました。

UPDATE x 
SET col_p = (
    SELECT sum(col_p) 
    FROM y 
    WHERE concat(x.mmonth, x.dday, x.yyear) = (concat(y.mmonth, y.dday, y.yyear)) 
     AND x.ID = y.ID 
    ) 

これが成功し、正しい値でcolumsを更新しますが、このように実行するために、それは実行するために15分かかり、私は〜40個の、より類似したクエリを持っている...だからどのように私はこれを高速化については行くだろうか?私はセット内の機能とどこが私を殺していると思います。

+1

[EXPLAIN](https://www.postgresql.org/docs/9.6/static/sql-explain.html)と「ANALYZE」を使用して、クエリの実行計画が何であるか確認しましたか?一般に、索引を使用していない可能性のある表スキャン全体を調べます。 –

+1

日付を別々の{日、月、年}の列に分割しないでください。代わりに、単一のDATE列型を使用します。 BTW:連結はおそらく'12/1/2017 'と' 1/21/2017 'を等しくないものとして比較します。 – joop

答えて

3

私は、クエリを書くことを示唆している:そして、あなたはy(ID, yyear, mmonth, dday, col_p)にインデックスを持っていることを確認してください

UPDATE x 
    SET col_p = (SELECT sum(col_p) 
       FROM y 
       WHERE x.yyear = y.yyear AND x.mmonth = y.mmonth AND 
         x.dday = y.dday AND x.ID = y.ID 
       ); 

+1

これは私のクエリが15分かかってから9秒で終了するまでうまくいきます。 – cblanto7

+1

@ cblanto7。 。 。 99%のスピードアップ。かなり良い。 –

1

あなたがすることができるものは、次のとおりです。

  1. はテーブルyを確保するには(列y.idが最初の列となっている)主キーによって到達されます。
  2. ヌル列がない場合は、concatが不要なようです。だからconcat(x.mmonth, x.dday, x.yyear) = (concat(y.mmonth, y.dday, y.yyear))ではなく、(x.mmonth, x.dday, x.yyear) = (y.mmonth, y.dday, y.yyear)を試してみてください。
  3. yが適切なプライマリキーを使用していることを確認したら、xにパラレルヒントを与えてupdateを作成できます。たとえば、4つの並列プロセスを使用するには、update /*+ PARALLEL(x 4) */ x ...この手順では、システムリソースを適切に使用するように注意してください。

だから私が示唆していることは、並列プロセスを経由してあなたが完全スキャンを行い、テーブルの主キー

  • 到達を経由して、あなたが「多くの時間を」行くテーブル、すなわちテーブルy、すなわちテーブルx

    • 届きます。
  • 関連する問題