Power BI データ モデリング: ビジネス インテリジェンスのためのスター スキーマ設計

スター スキーマ設計、ファクト テーブルとディメンション テーブル、DAX メジャー、計算グループ、タイム インテリジェンス、複合モデルを使用した Power BI データ モデリングをマスターします。

E
ECOSIRE Research and Development Team
|2026年3月17日6 分で読める1.3k 語数|

Power BI データ モデリング: ビジネス インテリジェンスのためのスター スキーマ設計

データ モデルは、すべての Power BI レポートの基礎です。適切に設計されたモデルにより、DAX の測定がシンプルになり、クエリのパフォーマンスが高速になり、レポートの開発が直感的に行われます。モデルの設計が不十分だと、すべてが困難になります。対策には複雑な回避策が必要で、クエリの実行は遅く、開発者は洞察を構築するよりもモデルとの格闘に多くの時間を費やします。

スター スキーマは、何十年もの間、分析データ モデルのゴールド スタンダードです。 ERP および CRM システムを強化するリレーショナル データベースは、相互接続された多数のテーブルを含む正規化されたスキーマを使用してトランザクション効率を高めるように設計されています。この設計は、個々のトランザクションを記録するのには最適ですが、集計、比較、傾向分析には適していません。スター スキーマは、同じデータをファクト テーブル (何が起こったのか) とディメンション テーブル (何が起こったのかに関するコンテキスト) に分離することで、分析パフォーマンスを向上させるために再構築します。

このガイドでは、ファクト テーブルとディメンション テーブルの構築、リレーションシップの構成、効率的な DAX メジャーの作成、計算グループの活用、タイム インテリジェンスの実装、複合モデルを使用して複数のデータ ソースに接続する方法など、Power BI に特化したスター スキーマの設計原則について説明します。

重要なポイント

  • スター スキーマはデータをファクト テーブル (数値メジャー、外部キー) とディメンション テーブル (記述属性) に分離します --- この構造は Power BI の VertiPaq エンジン用に最適化されています
  • Power BI モデル内のすべてのリレーションシップは、一方向のみのクロス フィルターを使用して、ディメンションからファクト (1 対多) に流れる必要があります。
  • VertiPaq はディメンション列を効率的に圧縮し、リレーションシップを通じてファクトをフィルタリングできるため、スター スキーマでは DAX メジャーのパフォーマンスが劇的に向上します。
  • 計算グループは、数十の冗長なメジャー (YTD、QTD、MTD、前年) を、すべての基本メジャーに適用される単一のパターンに置き換えます。
  • タイム インテリジェンスには専用の日付ディメンション テーブルが必要です --- 自動日付/時刻を使用したり、ファクト テーブルの日付列に依存したりしないでください
  • 複合モデルを使用すると、インポートされたデータを DirectQuery 接続と組み合わせて、メモリ内のパフォーマンスとライブ クエリの新鮮さを実現できます。
  • ロールプレイング ディメンション (複数のリレーションシップ ロールで使用される 1 つのテーブル) には、DAX の USERELATIONSHIP 関数が必要です

スタースキーマの基礎

Power BI にスター スキーマを使用する理由

Power BI のインメモリ エンジンである VertiPaq は、列圧縮を使用してデータを保存します。各列は個別に圧縮され、カーディナリティが低い (一意の値がほとんどない) 列は大幅に圧縮されます。1,000 万行にわたって 40 個の一意の値を持つ「国」列は、ほとんど圧縮されません。トランザクション ID やタイムスタンプなどのカーディナリティの高い列 (一意の値が多い) は、あまり圧縮されません。

スター スキーマは、カーディナリティの高いトランザクション データ (日付、金額、数量) を狭いファクト テーブルに分離し、カーディナリティの低い記述データ (名前、カテゴリ、地域) を別のディメンション テーブルに配置することでこれを利用します。その結果、メモリが小さくなり、クエリが高速化されたデータ モデルが得られます。

違いを考えてみましょう。小売業の非正規化フラット テーブルには、OrderDate、CustomerName、CustomerEmail、CustomerCity、Customer Country、CustomerSegment、ProductName、ProductCategory、ProductSubcategory、Brand、Supplier、Supplier Country、Quantity、UnitPrice、Discount、TotalAmount などの 50 列がある場合があります。各行には、「United States」が何千回も繰り返され、「Electronics」も何百回も繰り返され、顧客がこれまでに発注したすべての注文の完全な顧客名が表示されます。

スター スキーマに相当するものは、これを次のように分割します。

FactSales (狭い、注文明細ごとに 1 行): OrderDateKey、CustomerKey、ProductKey、Quantity、UnitPrice、Discount、TotalAmount。

DimCustomer: CustomerKey、CustomerName、電子メール、都市、国、セグメント。

DimProduct: ProductKey、ProductName、カテゴリ、サブカテゴリ、ブランド。

DimDate: DateKey、日付、年、四半期、月、MonthName、DayOfWeek。

ファクト テーブルには 50 列ではなく 7 列しかありません。各ディメンション テーブルには、それぞれの一意の値が 1 回だけ格納されます。 VertiPaq は、この構造をフラット テーブルより 3 ~ 5 倍圧縮し、エンジンが小さなディメンション テーブルをフィルタリングしてファクト テーブル内の一致する行のみを解決するため、クエリの実行が 2 ~ 10 倍高速になります。

ファクトテーブル: 設計原則

ファクト テーブルには、販売、注文、出荷、サポート チケット、Web 訪問、製造実行などのビジネス イベントが記録されます。各行は 1 つのイベントまたはイベントの 1 つの行項目を表します。

粒度の定義。 粒度は、ファクト テーブルの詳細レベルです。それを正確に定義し、一貫して適用します。売上ファクト テーブルには、「注文品目ごとに 1 行」または「日次製品売上概要ごとに 1 行」の粒度が含まれる場合があります。単一のファクト テーブル内でグレインを混在させると (一部の行は個別のトランザクションであり、一部の行は日次集計です)、デバッグが非常に困難な計算エラーが発生します。

外部キーのみ。 ファクト テーブルには、説明的な属性ではなく、ディメンション テーブルへの外部キーが含まれます。ファクト テーブルには、「CustomerName」または「ProductCategory」を含めることはできません。これらはディメンション テーブルに属します。ファクト テーブルには CustomerKey と ProductKey があり、説明的な詳細が存在するディメンションにリンクします。

加法的なメジャー。 ファクト テーブルの数値列は加法的である必要があります。つまり、任意のディメンションにわたって意味のある合計が可能な値である必要があります。収益、数量、コスト、割引は加算されます。パーセンテージ、比率、および単価は加算されません (製品全体の単価を合計することはできません)。コンポーネント (分子と分母) をファクト テーブルに保存し、DAX メジャーで比率を計算します。

ファクトでは計算列を避けてください。 ファクト テーブルに計算列を追加すると、テーブルのメモリ フットプリントが増加し、更新時の処理時間が増加します。代わりに DAX メジャーで派生値を計算します。これはクエリ時に計算され、ストレージを消費しません。

寸法表: 設計原則

ディメンション テーブルは、ビジネス イベントの「誰が、何を、どこで、いつ、なぜ」を記述します。これらには、ユーザーがフィルター、グループ化、スライスするための属性が含まれています。

サロゲート キー。 ディメンション テーブルの主キーとして、自然キー (顧客の電子メール、製品 SKU) ではなく、整数のサロゲート キー (CustomerKey、ProductKey) を使用します。代理キーはより小さく、圧縮率が高く、ソース システム キーの変更からモデルを隔離します。

ディメンションの非正規化。 スター スキーマでは、ディメンション テーブルは意図的に非正規化されます。 DimProduct テーブルには、Category、Subcategory、および Brand が、独自のキーを持つ個別の正規化されたテーブルとしてではなく、同じテーブル内の列として含まれています。これはトランザクション データベース設計の逆であり、意図的なものです。非正規化ディメンションでは、VertiPaq エンジンが複数のテーブルを結合するのではなく単一のテーブルをスキャンするため、より高速なクエリとよりシンプルな DAX が生成されます。

説明的な階層を含めます。 ユーザーがカテゴリ、サブカテゴリ、製品へとドリルダウンする場合、3 つのレベルすべてが DimProduct の列である必要があります。このドリル パスを定義する階層オブジェクトを Power BI モデルに作成します。

ゆっくりと変化するディメンション。 時間の経過とともにディメンションの属性が変化する場合 (顧客が都市を移動し、製品のカテゴリーが変化する場合)、戦略が必要になります。タイプ 1 (上書き) が最も単純です --- 新しい値でディメンション行を更新します。タイプ 2 (新しい行の追加) は履歴を保存します --- 有効な日付範囲を持つ新しい行を追加するため、履歴トランザクションはその時点で最新だった属性値に関連付けられます。タイプ 2 はより複雑ですが、履歴の正確性が重要な場合 (財務監査、規制報告) に必要です。


関係の構成

Power BI の関係ルール

Power BI リレーションシップは、テーブルの接続方法とフィルターの伝播方法を定義します。関係を正しくすることは非常に重要です。関係が間違っていると、暗黙のうちに間違った数値が生成されます。これは、エラーが発生するよりも悪いことです。

1 対多のみ。 スター スキーマのすべてのリレーションシップは、ディメンション テーブル (一方の側) をファクト テーブル (多側) に接続します。ディメンション テーブルのキー列には一意の値があります。ファクト テーブルには繰り返し値があります。 Power BI はこれを検証し、違反にフラグを立てます。 Power BI が多対多の関係を検出した場合は、修正する必要のあるモデリングの問題があります。

単一方向のクロス フィルタリング。 すべてのリレーションシップでクロス フィルタの方向を「単一」に設定します。これは、フィルターはディメンションからファクトに流れるが (スライサーで顧客を選択すると、その顧客の行のみがファクト テーブル ビジュアルに表示されます)、ファクトからディメンションに戻ることはないことを意味します。双方向フィルタリングは、複数のファクト テーブルを含むモデル内であいまいなフィルタ パスを作成するため、非常に特殊なシナリオを除いて回避する必要があります。

アクティブなリレーションシップと非アクティブなリレーションシップ Power BI では、2 つのテーブル間にアクティブなリレーションシップが 1 つだけ許可されます。ファクト テーブルに複数の日付列 (OrderDate、ShipDate、deliveryDate) がある場合は、アクティブなリレーションシップを 1 つ作成し (通常は OrderDate から DimDate まで)、その他のリレーションシップは非アクティブなリレーションシップを作成します。必要に応じて、DAX メジャーで USERELATIONSHIP 関数を使用して、非アクティブな関係をアクティブにします。

Shipped Revenue =
CALCULATE(
    [Total Revenue],
    USERELATIONSHIP(FactSales[ShipDateKey], DimDate[DateKey])
)

ロールプレイングの次元

ロールプレイング ディメンションは、モデル内で複数の役割を果たす単一のディメンション テーブルです。日付ディメンションは最も一般的な例です。日付ディメンションは、ファクト テーブルの OrderDate、ShipDate、および DeliveryDate に接続され、各リレーションシップで異なる「役割」を果たします。

Power BI では、ロールプレイング ディメンションを次の 2 つの方法で処理できます。

非アクティブなリレーションシップ + USERELATIONSHIP (推奨)。 1 つのアクティブなリレーションシップ (OrderDate に対する) と、他の日付列に対する非アクティブなリレーションシップを持つ単一の DimDate テーブルを保持します。代替日付パースペクティブに USERELATIONSHIP を使用するメジャーを作成します。これにより、モデルがコンパクトに保たれ、データの重複が回避されます。

ディメンション テーブルを複製します。 DimDate の個別のコピー (DimOrderDate、DimShipDate、DimdeliveryDate) を作成し、それぞれにそれぞれのファクト列とのアクティブな関係を設定します。このアプローチは、DAX の観点からは簡単ですが (USERELATIONSHIP は必要ありません)、モデルのサイズとメンテナンスの負担が増加します。

ほとんどの実装では、非アクティブな関係アプローチが推奨されます。より冗長な DAX を犠牲にして、よりクリーンなモデルとより小さいメモリ フットプリントを生成します。

多対多の関係

一部のビジネス シナリオでは、多対多の関係が本当に必要になります。顧客は複数のセグメントに属し、製品は複数のプロモーション キャンペーンに参加でき、営業担当者は複数の地域をカバーできます。スター スキーマはブリッジ テーブルを通じてこれらを処理します。

ブリッジ テーブルは、多対多の関係で 2 つのテーブルの間に位置し、組み合わせごとに 1 つの行が含まれます。

BridgeCustomerSegment: CustomerKey、SegmentKey

DimCustomer は BridgeCustomerSegment に接続します (CustomerKey で 1 対多)。 DimSegment は BridgeCustomerSegment に接続します (SegmentKey で 1 対多)。ブリッジ テーブルを使用すると、複数のセグメントの顧客を正しく処理しながら、セグメントごとに FactSales をフィルタリングできます。

ブリッジ テーブルには注意してください。多対多の割り当てを処理する適切な DAX メジャーと組み合わせないと、二重カウントが発生する可能性があります。既知のデータを使用して徹底的にテストし、合計が正しいことを検証します。


DAX の測定: パターンとパフォーマンス

基本対策

すべての分析モデルには、ファクト テーブルの列に対して単純な集計を実行する一連の基本メジャーが必要です。最初にこれらを定義します。これらは、より複雑な計算の構成要素として機能します。

Total Revenue = SUM(FactSales[TotalAmount])
Total Quantity = SUM(FactSales[Quantity])
Total Cost = SUM(FactSales[CostAmount])
Order Count = COUNTROWS(FactSales)
Average Order Value = DIVIDE([Total Revenue], [Order Count])
Gross Margin = DIVIDE([Total Revenue] - [Total Cost], [Total Revenue])

平均注文額と粗利益は、集計ロジックを繰り返すのではなく、他のメジャーを参照していることに注意してください。これは意図的なものです。総収益の定義が変更された場合 (たとえば、返品を除外するなど)、下流の測定値にその変更が自動的に反映されます。

計算: DAX の核心

CALCULATE は最も重要な DAX 関数です。変更されたフィルター コンテキストで式を評価します。 CALCULATE を理解することは DAX を理解することです。

Revenue Last Year =
CALCULATE(
    [Total Revenue],
    SAMEPERIODLASTYEAR(DimDate[Date])
)

このメジャーは、総収益メジャーを取得し、日付範囲が 1 年前にシフトされるフィルター コンテキストで評価します。現在のフィルター コンテキストが「2026 年 1 月」の場合、CALCULATE はそれを「2025 年 1 月」に変更し、その変更されたコンテキストで総収益を評価します。

CALCULATE は複数のフィルター引数を受け入れ、その型に応じて相互作用が異なります。

テーブル フィルター (SAMEPERIODLASTYEAR など) は、そのテーブルの列の既存のフィルターを置き換えます。ビジュアルにすでに月フィルターがある場合、SAMEPERIODLASTYEAR はそれを前年の対応する月でオーバーライドします。

ブール フィルター (DimProduct[Category] = "Electronics" など) は、既存のコンテキストに追加されます。ビジュアルを 2026 年にフィルターすると、CALCULATE 結果には 2026 年のエレクトロニクスの収益が表示されます。

REMOVEFILTERS は既存のフィルターをクリアします。 CALCULATE([Total Revenue], REMOVEFILTERS(DimProduct[Category])) は、どのカテゴリ フィルターがアクティブであるかに関係なく、すべてのカテゴリにわたる合計収益を返します。

可読性とパフォーマンスのための変数

変数 (VAR) は値を 1 回計算し、それを複数回参照します。複雑なメジャーを読みやすくし、冗長な計算を排除します。

Revenue YoY Growth =
VAR CurrentRevenue = [Total Revenue]
VAR PriorRevenue = [Revenue Last Year]
VAR Growth = CurrentRevenue - PriorRevenue
VAR GrowthPct = DIVIDE(Growth, PriorRevenue)
RETURN
    GrowthPct

変数を使用しない場合、このメジャーでは [総収益] と [昨年の収益] が複数回 (減算で 1 回、除算で 1 回) 計算されるため、計算コストが 2 倍になります。変数を使用すると、それぞれが正確に 1 回計算されるようになります。

イテレータ関数: いつ使用するか

反復関数 (SUMX、AVERAGEX、MAXX、MINX、COUNTX、RANKX) は、テーブル全体で式を行ごとに評価します。これらは強力ですが高価です --- 指定されたテーブル内のすべての行をスキャンします。

集計の前に行レベルの計算が必要な場合は、イテレータを使用します。

Weighted Average Price =
DIVIDE(
    SUMX(FactSales, FactSales[Quantity] * FactSales[UnitPrice]),
    SUM(FactSales[Quantity])
)

合計する前に各行で Quantity と UnitPrice を乗算する必要があるため、これは単純な SUM では実現できません。反復子 SUMX は、この行ごとの乗算を処理します。

単純な集計で十分な場合はイテレータを避けてください。 SUMX(FactSales, FactSales[TotalAmount]) は機能的には SUM(FactSales[TotalAmount]) と同等ですが、SUM が列圧縮を利用している間に反復子が行ごとにスキャンするため、速度が遅くなります。


計算グループ

計算グループが解決するもの

計算グループを使用する前は、10 個の基本メジャー (収益、数量、コスト、マージンなど) と 5 つのタイム インテリジェンス バリエーション (YTD、QTD、MTD、前年度、前年度 YTD) を含むデータ モデルには、50 個の個別のメジャーが必要でした。新しい基本メジャーを 1 つ追加するということは、さらに 5 つのタイム インテリジェンスのバリアントを作成することを意味します。新しいタイム インテリジェンス パターンを 1 つ追加すると、さらに 10 個のメジャーが作成されることになります。この組み合わせの爆発により、モデルの保守が困難になりました。

計算グループは、タイム インテリジェンス パターンを一度定義し、それを任意のメジャーに動的に適用することで、この問題を解決します。

タイム インテリジェンス計算グループの構築

Power BI Desktop で、モデル ビューを介して、または表形式エディター (より詳細な制御を提供する) などの外部ツールを使用して、計算グループを作成します。

タイムインテリジェンスパターンごとに計算項目を定義します。

現在: 変更なし --- メジャーをそのまま返します。

SELECTEDMEASURE()

YTD (年初から現在まで):

CALCULATE(
    SELECTEDMEASURE(),
    DATESYTD(DimDate[Date])
)

前年度:

CALCULATE(
    SELECTEDMEASURE(),
    SAMEPERIODLASTYEAR(DimDate[Date])
)

前年度YTD:

CALCULATE(
    SELECTEDMEASURE(),
    DATESYTD(SAMEPERIODLASTYEAR(DimDate[Date]))
)

前年比変化率:

VAR CurrentValue = SELECTEDMEASURE()
VAR PriorValue = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR(DimDate[Date]))
RETURN CurrentValue - PriorValue

前年比変化率:

VAR CurrentValue = SELECTEDMEASURE()
VAR PriorValue = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR(DimDate[Date]))
RETURN DIVIDE(CurrentValue - PriorValue, PriorValue)

定義したら、ユーザーが計算グループをビジュアルの列軸または行軸に配置すると、Power BI は各計算項目を値ウェル内のメジャーに適用します。 6 つの項目を含む 1 つの計算グループは、60 個の個別のメジャー (10 個の基本メジャーの場合) を置き換えます。

フォーマット文字列式

各計算項目には、計算に基づいて数値形式を動的に変更する形式文字列式を含めることができます。

絶対メジャー (現在、YTD、前年度) の場合: 基本メジャーの形式を使用します。 パーセンテージ指標 (YoY % Change) の場合: パーセンテージとしてフォーマットします。

// Format string for YoY % Change
"0.0%;-0.0%;0.0%"

これにより、ユーザーが「現在」($1,234,567 を表示) と「前年比 % 変化」(12.5% を表示) を切り替えたときに、手動介入なしで書式が正しく設定されることが保証されます。


タイムインテリジェンス

日付ディメンション テーブル

Power BI のタイム インテリジェンスには、専用の日付ディメンション テーブルが必要です。自動日付/時刻機能に依存しないでください ([ファイル] → [オプション] → [データ ロード] で無効にします)。すべての日付列に非表示の日付テーブルが作成され、モデルが肥大化して制御が制限されます。

データの全範囲と各側に少なくとも 1 年をカバーする日付ディメンション テーブルを作成します。最も早いトランザクションが 2020 年 1 月の場合は、日付テーブルを 2019 年 1 月から開始します。分析に 2027 年の予測が含まれる場合は、2027 年 12 月で終了します。

日付ディメンション テーブルの必須列:

コラム目的
日付キー20260317リレーションシップの整数キー
日付2026-03-17完全な日付 (データ型: 日付)
2026年暦年
四半期Q1四半期ラベル
四半期番号1四半期番号 (ソート用)
3月月の名前
月番号3月番号 (並べ替え用)
週番号12ISO 週番号
曜日火曜日曜日名
曜日番号3日番号 (ソート用)
週末です週末フラグ
休日休日フラグ (国別)
会計年度2026年度会計年度がカレンダーと異なる場合
会計四半期FQ4会計四半期

Power Query で、または DAX 計算テーブルとして日付テーブルを作成します。

DimDate =
VAR StartDate = DATE(2019, 1, 1)
VAR EndDate = DATE(2027, 12, 31)
RETURN
ADDCOLUMNS(
    CALENDAR(StartDate, EndDate),
    "DateKey", YEAR([Date]) * 10000 + MONTH([Date]) * 100 + DAY([Date]),
    "Year", YEAR([Date]),
    "Quarter", "Q" & QUARTER([Date]),
    "MonthNumber", MONTH([Date]),
    "Month", FORMAT([Date], "MMMM"),
    "DayOfWeek", FORMAT([Date], "dddd"),
    "IsWeekend", WEEKDAY([Date], 2) >= 6
)

Power BI でテーブルを日付テーブルとしてマークします (テーブル ツール → 日付テーブルとしてマーク → 日付列を選択)。これにより、組み込みのタイム インテリジェンス機能が有効になります。

一般的なタイム インテリジェンス パターン

適切な日付ディメンションを使用すると、Power BI のタイム インテリジェンス関数は、最も一般的な時間計算を処理します。

年初から現在まで: DATESYTD(DimDate[Date]) 四半期累計: DATESQTD(DimDate[Date]) 今月累計: DATESMTD(DimDate[Date]) 昨年の同時期: SAMEPERIODLASTYEAR(DimDate[Date]) ローリング 12 か月: DATESINPERIOD(DimDate[Date], MAX(DimDate[Date]), -12, MONTH) 並行期間: PARALLELPERIOD(DimDate[Date], -1, QUARTER) (同じサイズのウィンドウを後方にシフト)

これらの関数は、CALCULATE 内で使用されるときに日付フィルター コンテキストを変更します。これらは、日付列が、連続した完全な日付範囲を持つ日付テーブルとしてマークされたテーブルからのものである場合にのみ正しく機能します。

会計カレンダーのサポート

組織の会計年度が暦年と一致しない場合は、会計カレンダーを使用するようにタイム インテリジェンスの計算を変更します。

Fiscal YTD Revenue =
CALCULATE(
    [Total Revenue],
    DATESYTD(DimDate[Date], "6/30")  -- Fiscal year ends June 30
)

DATESYTD の 2 番目の引数は、会計年度末日を指定します。すべての YTD 計算では、12 月 31 日の代わりに会計年度境界が使用されます。


複合モデル

複合モデルを使用する場合

複合モデルは、インポートされたデータ (VertiPaq に保存されている) と DirectQuery データ (ソースからライブでクエリされた) を単一のモデルに結合します。このハイブリッド アプローチは、履歴分析のためにインポートされたデータのパフォーマンスが必要であり、運用メトリクスのためにライブ データの鮮度が必要な場合に役立ちます。

一般的なシナリオ:

履歴 + リアルタイム。 トレンド分析のために 3 年間の過去の売上データをインポートします (高速クエリ、ソース データベースには影響しません)。 DirectQuery 経由で当月のデータに接続し、最新の運用ビューを表示します。

中央モデル + ローカル エンリッチメント。 DirectQuery 経由で中央管理されたデータセットに接続します (組織の管理された定義を使用していることを確認します)。中央モデルに存在しない部門固有のデータ (予算目標、カスタム分類) については、ローカルにインポートされたテーブルを追加します。

複数のソース システム。 クラウド データ ウェアハウス (Snowflake、Azure Synapse) からデータをインポートし、単一のレポートで DirectQuery 経由で運用データベース (PostgreSQL、SQL Server) に接続します。統合するための個別の ETL パイプラインを構築する必要はありません。

複合モデルのアーキテクチャ

複合モデルでは、各テーブルにストレージ モードがあります。

インポート: データは VertiPaq メモリにロードされます。クエリのパフォーマンスは最速ですが、更新するにはスケジュールされた更新が必要です。

DirectQuery: データはソースからライブでクエリされます。常に最新ですが、ソース データベースのパフォーマンスに依存します。

デュアル: テーブルはインポートされ、DirectQuery で使用できます。 Import ファクト テーブルと DirectQuery ファクト テーブルの両方に関連付ける必要があるディメンション テーブルに使用されます。

Import ファクトと DirectQuery ファクトをブリッジするディメンション テーブルを「デュアル」モードに設定します。これにより、VertiPaq エンジンはインポート ファクトをフィルターするときにメモリ内コピーを使用し、DirectQuery ファクトをフィルターするときに SQL クエリを生成できるようになります。

パフォーマンスに関する考慮事項

複合モデルは複雑さをもたらします。 Import テーブルと DirectQuery テーブルにまたがるクエリでは、Power BI で 2 つの異なるエンジンからの結果をマージする必要がありますが、DirectQuery ソースが最適化されていない場合、処理が遅くなる可能性があります。

ほとんどの分析クエリがインポート テーブルにヒットするようにモデルを構造化することで、クロスソース結合を最小限に抑えます。 DirectQuery は、リアルタイムの鮮度が必要な特定のテーブルにのみ使用してください。リレーションシップとフィルターで使用される列の DirectQuery ソース テーブルにインデックスを付けます。

複雑な Power BI データ モデルを構築している組織向けに、ECOSIRE のデータ モデリング サービス は、特定のデータ ランドスケープとパフォーマンス要件に合わせたスター スキーマ設計、DAX 最適化、複合モデル アーキテクチャに関する専門家によるガイダンスを提供します。


モデルの最適化

モデルのサイズを縮小する

大規模なモデルはより多くのメモリを消費し、更新が遅くなり、クエリの応答性が低下します。次の手法を使用してモデル サイズを最適化します。

未使用の列を削除します。 列がビジュアル、メジャー、リレーションシップ、または RLS ルールで使用されていない場合は、列を削除します。すべての列は、視覚的に参照していない場合でもメモリを消費します。一般的な攻撃者には、自動生成列、監査列 (CreatedBy、ModifiedDate)、および分析目的を持たない技術識別子が含まれます。

カーディナリティを減らします。 数百万の一意の値 (タイムスタンプ、GUID、フリーテキスト フィールド) を含む列は、あまり圧縮されません。タイムスタンプを適切な粒度 (毎日、毎時) に丸めます。 GUID を整数の代理キーに置き換えます。フリーテキストフィールドを、ドリルスルー時にのみクエリされる別の詳細テーブルに移動します。

適切なデータ型を使用してください。 Power BI では、「10 進数」よりも「整数」の方が効率的に保存されます。列に整数 (数量、カウント) のみが含まれる場合は、そのタイプを整数に設定します。テキスト列は、同じカーディナリティの数値列よりも多くのメモリを消費します。可能であれば、テキスト カテゴリをルックアップ ディメンションの整数としてエンコードします。

自動日付/時刻を無効にします。 自動日付/時刻機能は、モデル内のすべての日付列に対して非表示の日付テーブルを作成します。 10 個の日付列を持つモデルの場合、10 個の非表示の日付テーブルがメモリを消費することになります。この機能を無効にし、代わりに単一の明示的な日付ディメンションを使用します。

クエリパフォーマンス診断

DAX Studio を使用して、Power BI の組み込みパフォーマンス アナライザーで示される以上のクエリ パフォーマンスを分析します。 DAX Studio では次のことが明らかになります。

ストレージ エンジン クエリ。 VertiPaq エンジンに送信されるクエリの数とスキャンされるデータの量。スキャンするクエリが少なくなり、より少ないデータが得られるということは、パフォーマンスが向上することを意味します。

数式エンジンのアクティビティ。 数式エンジンが行う作業量 (行ごとの計算、複雑な式)。フォーミュラ エンジン時間が長いということは、ストレージ エンジンにより多くの作業をプッシュするために書き直す必要があるメジャーを示しています。

クエリ プラン。 DAX クエリの論理的および物理的な実行プラン。Power BI がメジャーをストレージ エンジン クエリと数式エンジン操作に分解する方法を示します。

インタラクティブなビジュアルの場合、クエリ時間を 500 ミリ秒未満にすることを目標にします。 2 秒を超えるクエリは遅く感じられ、ダッシュボードの使用を妨げます。特定のビジュアルが常に 2 秒を超える場合は、その DAX を簡素化し、処理するデータ量を減らすか、ユーザーが短時間待つことを受け入れるドリルスルー ページに移動します。


よくある質問

Power BI ではスター スキーマとスノーフレーク スキーマを使用する必要がありますか?

Power BI には、ほとんどの場合、スター スキーマが適しています。 Snowflake スキーマは、ディメンション テーブルをサブテーブル (カテゴリ → サブカテゴリ → 製品) に正規化します。これはリレーショナル データベースではうまく機能しますが、Power BI の VertiPaq エンジンでは不要な結合が作成されます。 VertiPaq は非正規化ディメンション列を非常に効率的に圧縮するため、追加のリレーションシップによるパフォーマンス コストが実際に発生する一方で、スノーフレーキングによるスペースの節約は無視できます。特別な技術的理由がない限り、ディメンションをスター スキーマにフラット化します (たとえば、めったに使用されないカーディナリティの高い列を分離したい非常に大きなディメンション テーブルなど)。

Power BI の最大データセット サイズはどれくらいですか?

Power BI Pro は、最大 1 GB の圧縮データセットをサポートします。ユーザーごとのプレミアムは最大 100 GB をサポートします。プレミアム容量 (P1 以降) は、大規模なデータセット ストレージが有効になっている場合、最大 400 GB をサポートします。これらの制限は、ソース データのサイズではなく、圧縮されたメモリ内のサイズを指します。 VertiPaq は通常、10:1 の比率でデータを圧縮するため、1 GB の圧縮データセットは 10 GB のソース データを表す可能性があります。データセットがこれらの制限に近づいている場合は、詳細レベルのデータに対して、集計、増分更新、または DirectQuery を使用した複合モデルを検討してください。

スター スキーマで多対多の関係を処理するにはどうすればよいですか?

ブリッジ テーブル (ファクトレス ファクト テーブルまたはジャンクション テーブルとも呼ばれます) を使用します。ブリッジ テーブルには、多対多の関係の組み合わせごとに 1 行が含まれます。たとえば、顧客セグメントの割り当てごとに 1 行が含まれます。各ディメンションからブリッジ テーブルへの 1 対多のリレーションシップを作成します。ブリッジ テーブルでは二重カウントが発生する可能性があることに注意してください。これらを DISTINCTCOUNT メジャーと組み合わせるか、DAX の CROSSFILTER を使用してフィルターの伝播を制御します。既知のデータを使用して徹底的にテストし、合計が正しいことを確認します。

計算列または DAX メジャーを作成する必要がありますか?

ほとんどの場合、計算列よりもメジャーを優先します。メジャーはクエリ時に計算され、ストレージを消費しません。計算列はリフレッシュ中に計算されてメモリに保存されるため、モデルのサイズが増加します。計算列は、フィルタリング、並べ替え、またはリレーションシップに使用できる値が必要な場合にのみ使用します (スライサーのメジャーでフィルタリングすることはできませんが、計算列でフィルタリングすることはできます)。一般的な例外は、ユーザーがスライサーまたはテーブル ビジュアルで必要とする行レベルのラベル (FullName = FirstName + " " + LastName) の連結列です。

計算グループは既存のメジャーとどのように連携しますか?

計算グループは、計算項目の式でメジャーをラップすることにより、メジャー評価をインターセプトします。ビジュアルにメジャーと計算グループが含まれている場合、Power BI は SELECTEDMEASURE() 関数を介して計算項目をメジャーに適用します。これは、基本メジャーを変更する必要がないことを意味します。ただし、既にタイム インテリジェンスが含まれているメジャー (ハードコーディングされた YTD メジャーなど) では、計算グループが上に適用されるため、二重適用が発生する可能性があります。これを回避するには、基本メジャー (単純な集計) のみを定義し、すべての時間のインテリジェンスと比較ロジック専用に計算グループを使用します。

E

執筆者

ECOSIRE Research and Development Team

ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。

WhatsAppでチャット