2009-08-05 7 views
3

私はPostgreSQLデータベースへのログファイル用にETLをやっており、単純なスタースキーマにデータを読み込む際のパフォーマンスを最適化するために使用されるさまざまなアプローチについてもっと学びたいと思っています。SQL - バルクインサートと大きな結合のパフォーマンスを最適化しますか?

文脈で質問を置くためには、ここで私は現在、何をすべきかの概要です:

  1. ドロップすべての外部キーとユニーク 制約
  2. インポートしたデータ(約100万件のレコード)
  3. 再制約を作成し、ファクト表の分析を実行します。

データの読み込みは、ファイルからの読み込みによって行われます。

1)コピーを使用して一時テーブルにデータをロードする(PostgreSQLの一括アップロードツール)

2)任意の新しいデータがそのような各のためのインサートを用いて9次元テーブルの各々を更新:各ファイルについてよう:

INSERT INTO host (name) 
SELECT DISTINCT host_name FROM temp_table 
EXCEPT 
SELECT name FROM host; 
ANALYZE host; 

分析する(アップデートの数千万の過程で最新の統計を保つためのアイデアをINSERTの最後に実行このことをお勧めまたは必要です最低でもそれはないですか?性能を大幅に低下させるように見える)。

3)ファクトテーブルは、不浄9ウェイで更新されて参加:私が見渡せるんだが、より良いアプローチは

INSERT INTO event (time, status, fk_host, fk_etype, ...) 
SELECT t.time, t.status, host.id, etype.id ... 
FROM temp_table as t 
JOIN host ON t.host_name = host.name 
JOIN url ON t.etype = etype.name 
... and 7 more joins, one for each dimension table 

ていますか?あなたは(あなたがそれを挿入した後)にデータを挿入しているが、あなたは離れてこの情報を投げると、あなたとステージ3でそれを再発見している各次元の主キーを知っているステージ2の間に

答えて

1

ソースからのデータの正規化にいくつかのアプローチを試みましたが、一般的に私が今使っているアプローチが自分の選択であることがわかりました。それに従うのは簡単で、マイナーな変更は軽微です。ステージ2の間に生成されたIDを次元テーブルの1つから戻そうとすると、複雑なものに過ぎず、大きなデータセットに対して効率の良い小さなクエリが生成されます。 Postgresは、現代版ではあなたの「神聖な結合」で非常に効率的でなければならず、「select distinct except select」を使うとうまくいくはずです。他の人がもっとよく知っているかもしれませんが、私はあなたの現在の方法が私の推測された方法であることを発見しました。

0

"不潔な" 9-way結合。

代わりに、あなたのファクトテーブルに挿入するsprocを作成することをお勧めします。例えばinsertXXXFact(...)は、命名規則getOrInsertXXXDimに続いて、他の多くのsprocs(次元ごとに1つ)を呼び出します。XXXは問題の次元です。これらのsprocsはそれぞれ、指定されたディメンションの新しい行をルックアップまたは挿入し(参照整合性を保証する)、ファクト表が参照するディメンションの主キーを戻す必要があります。これにより、ステージ3で行う必要がある作業が大幅に削減されます。これはフォーム形式の呼び出しに還元されます sprocsで採用しているアプローチは、ダミー値を使用できない場合に挿入することです後でこれらの値を特定して豊かにするための別々の浄化プロセスが必要です。

+1

私は原則として同意しますが、私がそのアプローチを試みたとき、私はそれが平均で50%遅くなることを発見しました。ディメンションテーブルのキャッシングと、バルク操作(個々の選択/挿入ではなく)が高速であるため、すべてを実行するように見えます。 – Rob

+1

@Rob:それは過去に私のために働いたアプローチのように面白いです。 BTW私はこの答えが何のコメントもせずにdownvotedと信じられない! – Adamski

関連する問題