次の方法で共有


ホット テーブル パーティションとコールド テーブル パーティションを使用して、非常に大きな Power BI データ モデルを最適化する

この記事では、ホット テーブル パーティションとコールド テーブル パーティションを使用して、非常に大きなデータ モデルを最適化する方法について説明します。 パーティションは、テーブルのデータを個別のサブセットに分割する方法を提供します。 パーティションは標準の Power BI データ モデリング ツールでは直接公開 されません が、Power BI Desktop で増分更新ポリシーを構成することで、高度なパーティション分割方法を利用できます。 増分更新は、 データセットの増分更新とリアルタイム データで説明されているように、パーティションに依存します。 ただし、ホット テーブル パーティションとコールド テーブル パーティションの構成は、増分更新ポリシーで実現できる機能を超え、一般的なテーブル パーティション分割スキームと XMLA ベースのツールに精通していることを前提としています。

[前提条件]

このパーティション分割手法の相対的な複雑さのため、次の領域の経験を持つ上級ユーザーに最適です。

  1. テーブルパーティション分割の概念、インポート モードパーティション、 DirectQuery モード 、デュアルモード のしくみについて説明します。

  2. XMLA ベースのツールを使用してハイブリッド テーブルを作成する方法に関する知識。 ハイブリッド テーブルでは、1 つ以上のインポート モード パーティションと 1 つの DirectQuery パーティションが使用されます。

  3. DataCoverageDefinitionを指定するために使用できる DAX 関数の要件に関する知識。 これは、Power BI エンジンが必要に応じてクエリ処理からこのパーティションを除外できるように、ハイブリッド テーブルの DirectQuery パーティションに含まれるデータを記述するための DirectQuery パーティションの新しいプロパティです。 DirectQuery パーティションを除外すると、不要なデータ ソース クエリを回避し、DAX クエリ処理のパフォーマンスを向上させることができます。

  4. 通常のテーブル リレーションシップと制限されたテーブル リレーションシップの違いを理解する。 たとえば、RELATED 関数は、関連する日付ディメンション テーブルの値に基づいてファクト テーブル パーティションのデータ カバレッジを定義する場合に便利です。 ファクト テーブル パーティションは DirectQuery パーティションであり、RELATED 関数が値をフェッチできない日付テーブルとのリレーションシップが制限される可能性があることに注意してください。 このシナリオでは、RELATED は日付ディメンション テーブルがデュアル テーブルの場合にのみ機能します。 日付テーブルは 、DirectQuery または デュアル モードである必要があります。 純粋なインポートにすることはできません。

Power BI によって DataCoverageDefinition パーティションがクエリ処理から誤って除外される可能性があるため、正しく定義されていないが間違った結果を招く可能性があることに注意してください。 そのため、DataCoverageDefinition の有無で結果を比較し、それぞれの結果が一致することを確認してください。

ホット テーブル パーティションとコールド テーブル パーティションを使用するタイミング

ホット パーティションとコールド パーティションが、履歴分析用のハイブリッド テーブルの微調整に役立つ例を次に示します。 長年にわたって蓄積された非常に大規模なデータ ソースがあるとします。 主な用途は、過去 2 年間の最新のデータを分析することです。 場合によっては、古いデータを分析することもできます。 おそらく、最近の売上が前年比で急激に増加していることに気付いたと思います。 それは今まで起こったことがありますか? 売上追跡を開始して以来、最大の売上急増ですか?

ホット パーティションとコールド パーティションをサポートしていない場合、この種の履歴分析では、すべての履歴データと最新のデータをファクト テーブルにインポートする必要があります。 プライマリ分析では古い履歴データも使用されないため、これはリソースの非効率的な使用です。 最悪の場合、データ ボリュームは非常に大きいため、完全にインポートすることもできません。 データ モデルを DirectQuery モードに切り替え、インポート モードと比較してパフォーマンスの低下を受け入れるか、別のモデルを構築してユーザーにレポートを切り替える必要があります。 ホット パーティションとコールド パーティションを含むハイブリッド テーブルを使用すると、より優れたオプションが提供されます。

ホット テーブル パーティションとコールド テーブル パーティションの使用方法

まず、AdventureWorks サンプル データ モデルの FactInternetSales テーブルを次の図に示すように、最新のデータの ホット インポート モード パーティションを使用して売上テーブルを構成し、古いデータを コールドDirectQuery パーティションに保持します。 20200101以上の OrderDateKey を持つ行は、ホット インポート モード パーティションを介してデータ モデルにインポートされます。 OrderDateKey が20200101未満の行は、コールド DirectQuery パーティションでカバーされます。 これで、Power BI はインポート モードで主要なユース ケースを迅速に提供できます。 DirectQuery パーティションでこれをカバーしているため、たまにしか分析しない膨大な量の履歴データをインポートする必要はありません。

Adventure Works サンプル データ モデルの Fact Internet Sales テーブルのスクリーンショット。ファクト インターネット販売テーブルが開き、フィルター処理された行が表示されます。

AdventureWorks サンプル データ ウェアハウスがあり、それに従いたい場合は、一般的な手順を次に示します。

  1. データセットを作成します。 Power BI Desktop を使用して、AdventureWorks データセットとレポートを作成します。 すべてのテーブルを純粋 DirectQuery モードで含めます。 次に、 FactInternetSales テーブルを除くすべてのテーブルを デュアル モードに変換します。 FactInternetSales テーブルは DirectQuery モードのままにします。

  2. データセットをアップロードします。 書き込み操作用に XMLA エンドポイントを有効にして、Power BI Premium でホストされているワークスペースを使用します。

  3. 互換性レベルを更新します。 SQL Server Management Studio (SSMS) で AdventureWorks データセットを含むワークスペースを開きます。 AdventureWorks データセット>Script>Script Database asCreate または Replace to を右クリックし、[新しいクエリ エディター] ウィンドウを選択します。 compatibilityLevel プロパティを 1603 (以上) に設定します。 [ 実行] を選択するか、F5 キーを押します。 操作が正常に完了したことを確認します。

    互換性レベルが 1603 に設定されているスクリプトのスクリーンショット。

  4. FactInternetSales テーブル パーティションを構成しますAdventureWorks データセット>スクリプト>スクリプト データベースとして作成または置換先を右クリックし、[新しいクエリ エディター ウィンドウ]を選択します。 パーティション セクション全体を次のセクションに置き換えます。 環境内の AdventureWorksDW データベースを指すように Sql.Database 行を更新してください。 [ 実行] を選択するか、F5 キーを押します。 操作が正常に完了したことを確認します。

       "partitions": [ 
        { 
          "name": "FactInternetSales-DQ-Partition", 
          "mode": "directQuery", 
          "dataView": "full", 
          "source": { 
            "type": "m", 
            "expression": [ 
              "let", 
              "    Source = Sql.Database(\"demo.database.windows.net\", \"AdventureWorksDW\"),", 
              "    dbo_FactInternetSales = Source{[Schema=\"dbo\",Item=\"FactInternetSales\"]}[Data],", 
              "    #\"Filtered Rows\" = Table.SelectRows(dbo_FactInternetSales, each [OrderDateKey] < 20200101)", 
              "in", 
              "    #\"Filtered Rows\"" 
            ] 
          } 
        }, 
        { 
          "name": "FactInternetSales-Import-Partition", 
          "mode": "import", 
          "source": { 
            "type": "m", 
            "expression": [ 
              "let", 
              "    Source = Sql.Database(\"demo.database.windows.net\", \"AdventureWorksDW\"),", 
              "    dbo_FactInternetSales = Source{[Schema=\"dbo\",Item=\"FactInternetSales\"]}[Data],", 
              "    #\"Filtered Rows\" = Table.SelectRows(dbo_FactInternetSales, each [OrderDateKey] >= 20200101)", 
              "in", 
              "    #\"Filtered Rows\"" 
            ] 
          } 
        } 
      ],    
    
  5. データ モデルを処理します。 Power BI ポータルで、 AdventureWorks データセットを含むワークスペースを開き、データセットのオンデマンド更新を実行して、データを含むインポート パーティションを読み込みます。

  6. レポートに最近のデータと履歴データが表示されていることを確認します。 AdventureWorks を開き、次のスクリーンショットのように、2020 年 1 月 1 日以降の販売トランザクションの結果をレポートに表示できることを確認します。

2 つの異なるレポートのスクリーンショット。1 つは 2020 年のデータを示し、1 つは 2019 年のデータを示しています。

DirectQuery パーティションのデータ カバレッジを定義する

このソリューションは、最近のデータと履歴データに対してシームレスに機能します。 ただし、既定では、Power BI では、各パーティションに含まれるデータがわからないため、すべてのテーブル パーティションに対してクエリが実行されます。 そのため、Power BI は、DirectQuery パーティションがカバーしていない年数であっても DirectQuery パーティションに対してクエリを実行します。 売上データはインポート パーティションですぐに使用でき、DirectQuery パーティションは行を提供しませんが、この余分なソース クエリを実行しても、データ ソースに顕著な負荷が発生し、DAX クエリ処理に遅延が発生する可能性があります。 この余分なソース クエリを回避するには、 DataCoverageDefinitionを使用します。

次のスクリーンショットに示すように、Power BI レポートでは、各ビジュアルの DAX クエリによって Power BI が DirectQuery パーティションにクエリを実行するため、2020 の不要な SQL クエリがいくつかデータ ソースに送信されます。

DAX クエリのスクリーンショット。

次の TMSL スニペットのように dataCoverageDefinition パーティションに プロパティを設定することで、これらの SQL クエリは回避されます。 ただし、データ カバレッジ定義を適用または変更した後にデータセットを更新する必要があることに注意してください。 データ カバレッジ定義を評価するには、プロセスの再計算で十分です。 この手順を忘れると、パーティションにアクセスしようとするクエリがエラーになります。エラーメッセージは、「テーブル『[テーブル名]』のDQパーティションのDataCoverageDefinitionが最近の変更後にまだ計算されていません」と表示されます。 再処理する必要があります。

        { 
          "name": "FactInternetSales-DQ-Partition", 
          "mode": "directQuery", 
          "dataView": "full", 
          "source": { 
            "type": "m", 
            "expression": [ 
              "let", 
              "    Source = Sql.Database(\"demopm.database.windows.net\", \"AdventureWorksDW2020\"),", 
              "    dbo_FactInternetSales = Source{[Schema=\"dbo\",Item=\"FactInternetSales\"]}[Data],", 
              "    #\"Filtered Rows\" = Table.SelectRows(dbo_FactInternetSales, each [OrderDateKey] < 20200101)", 
              "in", 
              "    #\"Filtered Rows\"" 
            ] 
          },  
"dataCoverageDefinition": {  
                  "description": "DQ partition with all sales from 2017, 2018, and 2019.",  
                  "expression": "RELATED('DimDate'[CalendarYear]) IN {2017,2018,2019}"  
                }  
        } 

前述のように、 dataCoverageDefinition プロパティは不要なデータ ソースの読み込みを排除するのに役立ちます。 また、Power BI では必要に応じて DAX クエリ処理から DirectQuery パーティションを除外できるため、最近のデータの分析パフォーマンスも向上します。 単純な AND 演算子、OR 演算子、NOT 演算子を使用して、単一の値と範囲に対して単純なデータ カバレッジ式を定義できます。 RELATED 関数を使用して、ファクト テーブルと通常のリレーションシップを持つディメンション テーブルの列に基づいてデータ カバレッジを定義することもできます。 データ カバレッジ式でディメンション テーブルの列が使用されている場合は、ディメンション テーブルが デュアル モードであることを確認します。 ファクト テーブル自体の列に基づいてデータ カバレッジを定義することもできます。 サポートされている操作については、次の表を参照してください。3 つのグループに分類されています。 

タイプ Comments 例示
単一の述語(値を基準にした) 等値、不等値、および IN 演算子
ディメンション テーブルとファクト テーブルの両方をサポートする
RELATED('Date'[Year]) = 2020
NOT RELATED('Date'[Year]) = 2020
RELATED('Date'[Year]) IN {2020, 2021, 2022}
InternetSales'[SalesAmt] = CURRENCY(100.0)
「NOT InternetSales'[SalesAmt] = CURRENCY(100.0)」
InternetSales'[SalesAmt] IN {CURRENCY(100.0), CURRENCY(200.0)}
単一述語 (範囲ベース) >、<、>=、<= などの比較演算子を指定できます。
ディメンション テーブルをデュアル モードにする必要がある
RELATED('Date'[Year]) > 2020
RELATED('Date'[Year]) <= 2020
複数の述語 等値、不等値、および比較
IN 演算子をサポートしていません
デュアル モードの 1 つのディメンション テーブルに制限
RELATED('Date'[Year]) > 2010 > RELATED('Date'[Year]) > 2020
関連('Date'[Year]) = 2020 かつ 関連('Date'[Calendar Quarter]) = 1
RELATED('Date'[Year]) > 2020 > NOT RELATED('Date'[Calendar Quarter]) = 1
RELATED('Date'[Year]) > 2020 > RELATED('Date'[Calendar Quarter]) < 3
RELATED('Date'[Year]) > 2020 > (RELATED('Date'[Calendar Quarter]) = 1 ||RELATED('Date'[Calendar Quarter]) = 2)

DataCoverageDefinition パーティションの プロパティを使用すると、データ ソースの不要なクエリを回避することで、インポート モードのホット パーティションと DirectQuery モードのコールド パーティションに基づいて、最大の Power BI データ モデルを最適化できます。 このソース クエリの削減は、ホット データを分析するときにレポートのパフォーマンスを向上するのに役立ちます。 また、データ ソースの負荷を減らすのに役立ちます。この方法では、データ ソースのスケールを最大化するのに役立ちます。 ただし、 dataCoverageDefinition プロパティを使用してデータ モデルを最適化することは、依然として高度なシナリオであることに注意してください。 結果は慎重に確認してください。

考慮事項と制限事項

  • 現在、DataCoverageDefinition パーティションの プロパティには、RELATED('Date'[Year]) = 2020 や RELATED('Date'[Year]) IN {2020, 2021, 2022} などの静的な値が必要です。 RELATED('Date'[DateKey]) = TODAY() など、動的割り当てはサポートされていません。

  • リアルタイム データを使用した増分更新では、 DataCoverageDefinition プロパティは利用されません。 DirectQuery (リアルタイム) パーティションにデータ カバレッジ定義を適用すると、パーティションを再作成するときに、増分更新によってデータ カバレッジ定義が削除されます。