performance-optimization について
Power BI 開発者向けのパフォーマンス最適化スキルです。モデル、DAX、レポートのビジュアルを診断・改善し、Performance Analyzer と DAX Studio を使った分析手順を紹介します。
主な機能
- 01Performance Analyzer による遅いビジュアルの特定
- 02DAX Studio でのクエリプランとエンジン時間の分析
- 03VertiPaq のモデルサイズと圧縮の確認
- 04データモデル、リレーション、パーティションの最適化
- 05DAX 式とレポートビジュアルの改善
活用シーン
- 01レポートページの応答遅延の調査
- 02セマンティックモデルのメモリ使用量削減
- 03複雑または遅い DAX メジャーの最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill performance-optimizationインストール後、Claude Code で/performance-optimizationを入力して読み込まれたか確認します。
同梱ファイルreferences/advanced-capacity-patterns.mdreferences/dax-studio-walkthrough.md
詳細
パフォーマンスの最適化
概要
Power BI のパフォーマンスは、データモデルの設計、DAX の効率性、ビジュアルの構成、インフラストラクチャによって決まります。このスキルでは、高速で応答性の高いレポートを実現するための診断ツール、最適化手法、ベストプラクティスを紹介します。
診断ツール
パフォーマンス アナライザー(組み込み)
Power BI Desktop で有効にします:表示 > パフォーマンス アナライザー > 記録の開始
| 指標 | 意味 | 遅い場合の対処 |
|---|---|---|
| DAX クエリ | DAX の実行時間 | メジャーを最適化し、フィルターコンテキストを確認します |
| ビジュアルの表示 | 結果のレンダリング時間 | データポイントを減らし、ビジュアルを簡素化します |
| その他 | さまざまなオーバーヘッド | 通常はわずかです。大きな割合を占めない限り無視します |
ワークフロー:
- 記録を開始します
- ビジュアルのキャッシュをクリアします(「ビジュアルの更新」をクリック)
- レポートを操作します(スライサーを変更する、ページ間を移動する)
- 遅いビジュアルの DAX クエリをコピーします
- 詳しく分析するため、DAX Studio に貼り付けます
DAX Studio
DAX のパフォーマンスを詳しく分析するための無料の外部ツールです。
主な機能:
- 実行時間を測定しながら DAX クエリを実行
- サーバータイミング:ストレージエンジン(SE)と数式エンジン(FE)の時間を表示
- クエリプラン:論理クエリプランと物理クエリプランを表示
- VertiPaq Analyzer:モデルサイズと圧縮を分析
- すべてのクエリのトレース:レポートから送信されたすべてのクエリをキャプチャ
サーバータイミングの内訳:
| エンジン | 処理内容 | 最適化の対象 |
|---|---|---|
| ストレージエンジン(SE) | VertiPaq データをスキャンして行を取得 | カーディナリティとスキャンする列を減らします |
| 数式エンジン(FE) | DAX 式を評価 | DAX を簡素化し、ネストしたイテレーターを避けます |
**理想的な比率:**合計時間の 80~90% を SE が占める状態が理想です。FE の割合が高い場合は、DAX が過剰な計算を行っていることを意味します。
DAX Studio の一般的なワークフロー:
- Power BI Desktop(または XMLA エンドポイント)に接続します
- サーバータイミングを有効にします(クエリ > サーバータイミング)
- パフォーマンス アナライザーから DAX クエリを貼り付けます
- 実行して、時間の内訳を分析します
- 次の項目を確認します:
- SE クエリの数が多い(マテリアライズに問題があることを示します)
- SE クエリ内の CallbackDataID(処理のためにデータが FE に送られます。避けてください)
- FE 時間が長い(DAX が複雑すぎます)
- SE の行数が多い(スキャンするデータが多すぎます)
VertiPaq Analyzer
DAX Studio でモデルサイズと圧縮を分析します:詳細 > メトリックの表示
| 指標 | 確認内容 | 目標 |
|---|---|---|
| テーブルサイズ(バイト) | 最も大きいテーブルを特定します | 列を減らし、未使用の列を削除します |
| 列のカーディナリティ | カーディナリティが高いと圧縮効率が低下します | 個別の値を減らし、出現頻度の低い値をグループ化します |
| 列サイズ | ほかと比べてサイズが大きい列 | 削除するか、ディメンションに移します |
| ディクショナリサイズ | サイズの大きい文字列ディクショナリ | 文字列を短くするか、キーを使用します |
| リレーションシップサイズ | リレーションシップのマッピングに必要なメモリ | 通常は最適化できません |
| 階層サイズ | 非表示の自動日付/時刻階層 | 自動日付/時刻を無効にします |
データモデルの最適化
列の最適化
| 手法 | 効果 | 方法 |
|---|---|---|
| 未使用の列を削除 | 高 | ビジュアル、メジャー、リレーションシップのいずれにも使われていない列を削除します |
| 列のカーディナリティを減らす | 高 | 出現頻度の低い値をグループ化します(下位 5% を「その他」にまとめます) |
| 整数キーを使用 | 高 | テキストの外部キーを整数のサロゲートキーに置き換えます |
| 日付と時刻を分割 | 中 | DateTime を日付列と時刻列に分けます |
| 小数を丸める | 中 | 小数点以下 15 桁ではなく 2 桁に丸めます |
| 計算列を避ける | 中 | 代わりにメジャーを使用します(クエリ時の計算とストレージの違い) |
| 自動日付/時刻を無効にする | 中 | オプション > データの読み込み > チェックを外します |
| ファクトテーブルからテキストを削除 | 高 | 説明をディメンションテーブルに移します |
リレーションシップの最適化
- 単方向のクロスフィルターを使用します(双方向は避けます)
- DirectQuery リレーションシップでは「参照整合性を仮定する」を有効にします
- 未使用または冗長なリレーションシップを削除します
- リレーションシップには整数のキー列を使用します
パーティション戦略
大規模なテーブルは、日付範囲でパーティション分割します。
- 履歴パーティション(年次/四半期ごと)-- 更新頻度は低め
- 最新パーティション(当月/当週)-- 頻繁に更新
- 増分更新を使用して、パーティション管理を自動化します
DAX の最適化
効果の高いパターン
繰り返し計算を避けるために変数を使用します。
// BAD: Calculates [Total Sales] three times
Margin % = DIVIDE([Total Sales] - [Total Cost], [Total Sales])
// GOOD: Single calculation, reuse via variable
Margin % =
VAR Sales = [Total Sales]
VAR Cost = [Total Cost]
RETURN DIVIDE(Sales - Cost, Sales)
CALCULATE で大規模なテーブルに対して FILTER を使用しないようにします。
// BAD: Scans entire table
CALCULATE([Sales], FILTER(ALL(Products), Products[Category] = "Electronics"))
// GOOD: Column filter (optimized)
CALCULATE([Sales], Products[Category] = "Electronics")
ネストされたイテレーターを避けます。
// BAD: O(n^2) complexity
SUMX(Products,
SUMX(FILTER(Sales, Sales[ProductID] = Products[ProductID]),
Sales[Amount]))
// GOOD: Use relationship + simple aggregation
SUMX(Products, [Total Sales])
COUNTROWS(DISTINCT(...)) ではなく DISTINCTCOUNT を使用します。
// BAD
COUNTROWS(DISTINCT(Sales[CustomerID]))
// GOOD
DISTINCTCOUNT(Sales[CustomerID])
メジャーで FORMAT() を避けます(テキストが返され、並べ替えができなくなります)。
// BAD: Returns text, cannot sort
MonthLabel = FORMAT([Date], "MMMM yyyy")
// GOOD: Use a pre-computed column in the Date table for display
// And a numeric sort column for ordering
メジャーの複雑さに関するガイドライン
| 複雑さ | 使用が許容される対象 | パフォーマンス上の懸念 |
|---|---|---|
| 単純な集計(SUM、COUNT) | すべてのビジュアル | なし |
| 列フィルターを使用する CALCULATE | すべてのビジュアル | なし |
| 単一のイテレーター(SUMX) | ほとんどのビジュアル | 行数に注意 |
| FILTER(table) を使用する CALCULATE | 限られたビジュアル | テーブルが大規模な場合はあり |
| ネストされたイテレーター | 避ける | 常にあり |
| SUMX 内の CALCULATE | 慎重に使用 | コンテキスト遷移のコスト |
ビジュアルの最適化
ビジュアル数を減らす
| 問題 | 影響 | 対処法 |
|---|---|---|
| 1 ページに 20 個以上のビジュアル | 各ビジュアルが DAX クエリを送信 | 1 ページあたり 8~12 個に抑える |
| データポイントが多いビジュアル | 大きな結果セット | 上位 N 件や集計を使用 |
| 多数のスライサー | スライサーを変更するたびに、すべてのビジュアルに対してクエリが再実行される | 「適用」ボタンを使用 |
クエリの削減
クエリ削減機能を有効にします。
- レポートの設定 > クエリの削減 > スライサーに適用ボタンを追加 -- すべてのスライサーを変更した後、ユーザーが「適用」をクリックします
- 送信されるクエリ数を削減 > クロスハイライトを既定で無効にする -- ビジュアル間のクエリを削減します
条件付き書式
大規模なテーブルで、DAX ベースの複雑な条件付き書式を使用しないでください。単純な列参照、または計算量が限られたメジャーを使用します。
高度なキャパシティとモデルのパターン
集計、複合モデル、Direct Lake のパフォーマンス、大規模データセットの最適化(10GB 以上のセマンティックモデル)、Power BI Desktop のパフォーマンス設定、Power BI Report Server のチューニング、ブックマーク/フィルターの最適化に関する詳細なガイダンスは、references/advanced-capacity-patterns.md にあります。基本的な DAX/モデル/ビジュアルの改善を超えて、エンタープライズ規模のモデルをチューニングする場合は、このリファレンスを読み込んでください。
パフォーマンスチェックリスト
データモデル
- スタースキーマ設計(ファクトテーブル+ディメンションテーブル)
- 自動日付/時刻を無効化
- 未使用の列なし
- リレーションシップに整数キーを使用
- クロスフィルターの方向を単一に設定
- テキスト列はディメンションテーブルのみに配置
- 可能な場合、計算列をメジャーに変換
- カーディナリティの高い列に対処
DAX
- 繰り返し使用する式に変数を使用
- CALCULATE で大規模なテーブルに対する FILTER を使用しない
- ネストされたイテレーターなし
- COUNTROWS(DISTINCT(...)) より DISTINCTCOUNT を優先
- 並べ替えに使用するメジャーで FORMAT を使用しない
- メジャーがテキストではなく数値型を返す
ビジュアル
- 1 ページあたりのビジュアルは最大 8~12 個
- スライサーに適用ボタンを設定
- 大規模なテーブルに上位 N 件を適用
- 負荷の高いページではクロスハイライトを最小限にする
- 条件付き書式で単純な式を使用
インフラストラクチャ
- ワークロードに適したキャパシティサイズ
- 大規模なモデル(1GB 超)には Premium/Fabric を使用
- ゲートウェイを最適化(十分な RAM、SSD、データソースに近い場所)
- 大規模なテーブルに増分更新を設定
- DirectQuery の負荷が高いクエリに集計を使用
Direct Lake(該当する場合)
- Delta テーブルへの書き込みで V-Order を有効化
- 適切な頻度でフレーミングをスケジュール
- ファイル数/行グループ数がキャパシティのガードレール内
- フォールバック動作を設定して監視
- 計算列がフォールバックに与える影響をテスト
レポートサーバー(該当する場合)
- レポートサーバーのデータベースが PBIRS プロセスから分離されている
- ピーク時の同時ユーザー数に対応できる十分な CPU コアがある
- データベース用に IOPS の高い SSD ストレージがある
- 人気のあるレポートのレポートキャッシュが設定されている
- 同時ユーザー数が 50 人を超える場合は、NLB を使用してスケールアウトする
追加リソース
参考ファイル
references/dax-studio-walkthrough.md— クエリプランの解釈と DAX Studio の最新機能を含む、DAX Studio による分析のステップバイステップガイド