1

自己参照キーを含むディメンション テーブルを読み込もうとしていますが、最も効率的/効果的な方法を理解したいと考えています。

私のセットアップは次のとおりです。私のステージング環境には、メッセージの主キーとスレッド内の最初のメッセージの自己参照外部キーの 2 つのキーを含むメッセージ テーブルがあります。キー以外のすべてを取り除いた単純化されたテーブル構造:

CREATE TABLE [dbo].[MsgMain](
    [MsgMain_SK] [int] IDENTITY(1,1) NOT NULL,
    [MsgMainPK1] [int] NULL,
    [ThreadPK1] [int] NULL
) ON [PRIMARY]

MsgMain_SK のクラスター化インデックスと共に、両方のキーを含む非クラスター化インデックスがあります。

CREATE NONCLUSTERED INDEX [IX_MsgMain] ON [dbo].[MsgMain]
(
    [MsgMainPK1] ASC,
    [ThreadPK1] ASC
)

そのメッセージ テーブルからディメンション テーブルにデータをロードしています。

CREATE TABLE [dbo].[DimDiscussionPost](
    [DiscussionPost_SK] [bigint] IDENTITY(1,1) NOT NULL,
    [SrcDiscussionPostID] [int] NULL,
    [ThreadStarter_SK] [int] NULL
) ON [PRIMARY]

(私はまだそのテーブルにインデックスを作成していませんが、同じセットアップに従う予定です: SK でクラスター化され、ビジネスおよび外部キーでクラスター化されていません)。

私の初期ロード プロセスは次のようになります (SSIS ETL パッケージに変換されます)。

INSERT INTO [dbo].[DimDiscussionPost]
  (
    [SrcDiscussionPostID]
  )
SELECT 
    MM.MsgMainPK1 AS SrcDiscussionPostID
FROM 
    GradebookSTG9.dbo.MsgMain MM 

最初のレコードをロードした後、戻って次のUPDATEステートメントを実行します。

UPDATE dDP
SET dDP.ThreadStarter_SK = dTS.DiscussionPost_SK
FROM 
    GradeBookSTG9.dbo.MsgMain MM 
     INNER JOIN
    MasterDM.dbo.DimDiscussionPost dDP ON 
        dDP.SrcDiscussionPostID = MM.MsgMainPK1
     INNER JOIN 
    MasterDM.dbo.DimDiscussionPost dTS ON 
        MM.ThreadPK1 = dTS.SrcDiscussionPostID 

質問 1:これらのプロセスの両方を 1 つのステップで行う方法はありますか?

質問 2: ThreadPK1 のビジネス キーを MsgMainPK1 と共にテーブルに格納すると (つまり、SrcThreadStarterID を追加すると)、更新はより効率的になりますか?

質問 3:これを SSIS (ETL) パッケージに変換した後、次のようにしたほうがよいでしょうか。

  1. 各行がロードされると起動するトリガー (重要な場合は、一括挿入を使用しています)
  2. 新しく作成/更新されたすべてのレコードに対して上記の UPDATE ステートメントを実行する SQL 実行タスク
  3. 同じ論理 UPDATE を実行するルックアップおよび一括更新データ フロー
  4. あなたが提案しようとしている他の言いようのない独創的なもの

サンプルデータ:

+-----------------+-----------+
|     MsgMainPK1  | ThreadPK1 |
|     1234        | 1234      |
|     1235        | 1234      |
|     1236        | 1234      |
|     1237        | 1234      |
|     1238        | 1234      |
|     1239        | 1239      |
|     1240        | 1240      |
|     1241        | 1240      |
|     1242        | 1234      |
+-----------------+-----------+

必要なデータ:

+-------------------+---------------------+------------------+--------------------+
| DiscussionPost_SK | SrcDiscussionPostID | ThreadStarter_SK | SrcThreadStarterID |
+-------------------+---------------------+------------------+--------------------+
|                 1 |                1234 |                1 |               1234 |
|                 2 |                1235 |                1 |               1234 |
|                 3 |                1236 |                1 |               1234 |
|                 4 |                1237 |                1 |               1234 |
|                 5 |                1238 |                1 |               1234 |
|                 6 |                1239 |                6 |               1239 |
|                 7 |                1240 |                7 |               1240 |
|                 8 |                1241 |                8 |               1240 |
|                 9 |                1242 |                1 |               1234 |
+-------------------+---------------------+------------------+--------------------+
4

1 に答える 1

1

あなたはそれを一度に行うことができます。

WITH ordered_messages AS
(
  SELECT ThreadPK1, MsgMainPK1, 
    ROW_NUMBER() OVER(PARTITION BY ThreadPK1 ORDER BY MsgMainPK1) seq
  FROM MsgMain
)
INSERT INTO DimDiscussionPost(SrcDiscussionPostID, ThreadStarter_SK)
SELECT mm.MsgMainPK1, om.seq
FROM MsgMain mm
INNER JOIN ordered_messages om on om.ThreadPK1 = mm.ThreadPK1 and om.seq=1

3番目の質問の意味がよくわかりません。データをステージング テーブルにロードしてから、データをディメンション テーブルに挿入する必要があります。このプロセスは、ソース データの可用性、つまりファイルの到着、または SLA で指定された特定の時刻によってトリガーされる必要があります。残念ながら、私はあなたの輸入プロセスについて十分に知りません。

于 2014-11-15T08:05:55.433 に答える