⚖️ STEP 36: DAXの計算列とメジャーの違い
使い分けをマスターしてパフォーマンスを最適化!
📋 このステップで学ぶこと
- 計算列(Calculated Column)の仕組みと特徴
- メジャー(Measure)の仕組みと特徴
- パフォーマンスへの影響の違い
- 使い分けの判断基準
- 実践的な使い分け例
- よくある間違いと対策
ゴール:計算列とメジャーを適切に使い分け、効率的なデータモデルを構築できるようになる
📋 1. 計算列(Calculated Column)の詳細
計算列とは
計算列は、テーブルの各行に対して計算を実行し、結果を新しい列として保存します。データ更新時に一度だけ計算され、その後はメモリに保存されます。Excelの列に数式を入れるイメージです。
| 項目 | 説明 |
|---|---|
| 計算タイミング | データ更新(リフレッシュ)時に1回だけ計算 |
| 保存場所 | テーブル内に列として物理的に保存される |
| メモリ使用量 | すべての行の値を保存するため、使用量が多い |
| 計算対象 | 現在の行のデータ(行コンテキスト) |
| 参照方法 | [列名] または テーブル[列名] |
| 作成場所 | データビューまたはモデルビューで列を追加 |
| 使用場所 | 使用可否 | 例 |
|---|---|---|
| スライサー | ○ 使える | 年齢層でフィルタリング |
| フィルター | ○ 使える | 顧客ランクでフィルター |
| 行・列(軸) | ○ 使える | グラフのX軸に年齢層 |
| 値 | ○ 使える | テーブルに利益列を表示 |
| ツールチップ | ○ 使える | 詳細情報として表示 |
【例1: フルネーム】
フルネーム = 顧客[姓] & " " & 顧客[名]
結果(テーブルに保存される):
姓 名 フルネーム
────── ────── ──────────────
山田 太郎 山田 太郎
佐藤 花子 佐藤 花子
田中 次郎 田中 次郎
【例2: 利益(行レベル)】
利益 = 売上[売上金額] - 売上[原価]
結果:
売上金額 原価 利益
────────── ──────── ────────
10,000 6,000 4,000
15,000 9,000 6,000
8,000 5,000 3,000
【例3: 年齢層の分類】
年齢層 =
SWITCH(
TRUE(),
顧客[年齢] < 20, "10代",
顧客[年齢] < 30, "20代",
顧客[年齢] < 40, "30代",
顧客[年齢] < 50, "40代",
"50代以上"
)
結果:
年齢 年齢層
────── ──────────
25 20代
35 30代
18 10代
52 50代以上
| ケース | 説明と例 |
|---|---|
| スライサー/フィルター | 計算結果でフィルタリングしたい(例:年齢層、顧客ランク) |
| 行ごとの値 | 各行で異なる計算結果が必要(例:利益、フルネーム) |
| 文字列操作 | テキストの結合・分割(例:姓+名、住所の一部抽出) |
| カテゴリ分類 | IF/SWITCHによる分類(例:売上ランク、地域グループ) |
| ビジュアルの軸 | グラフの行・列に配置(例:X軸に年齢層) |
📊 2. メジャー(Measure)の詳細
メジャーとは
メジャーは、ビジュアルが表示されるたびにその場で動的に計算される集計値です。フィルターやスライサーの状態に応じて、値が動的に変わります。メモリには計算式のみ保存されます。
| 項目 | 説明 |
|---|---|
| 計算タイミング | ビジュアル表示時に毎回動的に計算 |
| 保存場所 | 計算式のみ保存(データは保存しない) |
| メモリ使用量 | 計算式のみなので、使用量が少ない |
| 計算対象 | フィルターされたデータセット全体(フィルターコンテキスト) |
| 参照方法 | [メジャー名] |
| 作成場所 | モデリングタブ→「新しいメジャー」 |
| 使用場所 | 使用可否 | 理由 |
|---|---|---|
| 値(数値部分) | ○ 使える | 本来の用途、動的に集計 |
| ツールチップ | ○ 使える | 補足情報として集計値を表示 |
| スライサー | × 使えない | 固定値がないため選択肢にできない |
| 行・列(軸) | × 使えない | カテゴリとして使えない |
| フィルター | × 使えない | 固定値がないため絞り込めない |
【メジャー例】 合計売上 = SUM(売上[金額]) 【フィルターによる動的変化】 フィルターなし: └─ 全体の合計 → 1,000,000円 地域 = "東京" でフィルター: └─ 東京の合計 → 350,000円 商品別に分割: ├─ 商品A → 400,000円 ├─ 商品B → 350,000円 └─ 商品C → 250,000円 年月 × 地域 で分割: ├─ 2024年1月 × 東京 → 50,000円 ├─ 2024年1月 × 大阪 → 40,000円 ├─ 2024年2月 × 東京 → 55,000円 └─ ... 同じメジャーなのに、コンテキストに応じて値が変わる!
| ケース | 説明と例 |
|---|---|
| 集計 | 合計、平均、カウント、最大、最小(例:SUM、AVERAGE、COUNT) |
| KPI | 重要指標の計算(例:売上、利益率、成長率) |
| 動的計算 | フィルターで変化する値(例:選択期間の売上) |
| 比率 | 構成比、前年比、達成率(例:DIVIDE、時系列関数) |
| 複雑な計算 | CALCULATE、タイムインテリジェンス関数 |
⚡ 3. パフォーマンスへの影響
なぜメジャーの方が効率的なのか
計算列とメジャーでは、メモリ使用量や計算速度に大きな違いがあります。特に大規模データでは、この差が顕著になります。
【シナリオ: 100万行のテーブルで利益を計算】 ┌────────────────────────────────────────────────────┐ │ 計算列の場合 │ ├────────────────────────────────────────────────────┤ │ 利益(列) = 売上[売上金額] - 売上[原価] │ │ │ │ メモリ使用量: │ │ ├─ 100万個の数値を保存 │ │ ├─ 非圧縮: 約8MB(数値1つ = 8バイト) │ │ └─ 圧縮後: 約4-5MB │ └────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────┐ │ メジャーの場合 │ ├────────────────────────────────────────────────────┤ │ 合計利益 = SUM(売上[売上金額]) - SUM(売上[原価]) │ │ │ │ メモリ使用量: │ │ ├─ 計算式のみ保存 │ │ └─ 数KB程度 │ └────────────────────────────────────────────────────┘ 差分: 計算列は約1000倍のメモリを使う!
| 観点 | 計算列 | メジャー |
|---|---|---|
| メモリ使用量 | 多い(全行保存) | 少ない(式のみ) |
| データ更新時 | 遅い(全行計算) | 速い(計算不要) |
| ビジュアル表示時 | 速い(保存済み) | 速い(最適化済み) |
| フィルター変更時 | 速い(再計算不要) | 速い(差分計算) |
| 100万行での影響 | 更新に数分かかる可能性 | 更新は高速 |
| 計算列のタイプ | 圧縮率 | 理由 |
|---|---|---|
| カテゴリ分類(年齢層など) | 高い(90%以上) | パターン数が少ない(5種類程度) |
| フラグ(True/False) | 非常に高い | 2パターンのみ |
| 数値計算(利益など) | 低い(30-50%) | 各行で異なる値 |
| 文字列結合(名前など) | 低い | ユニークな値が多い |
結論:圧縮が効かない計算列(数値計算など)は、メジャーに置き換えるべき!
🎯 4. 使い分けの判断基準
迷った時の判断フロー
計算列とメジャーのどちらを使うべきか、以下のフローチャートで判断できます。
質問1: スライサーやフィルターとして使う? ├─ YES → 計算列 ✓ └─ NO → 質問2へ ↓ 質問2: 行ごとに異なる値が必要? ├─ YES → 計算列 ✓ └─ NO → 質問3へ ↓ 質問3: 集計(合計、平均など)? ├─ YES → メジャー ✓ └─ NO → 質問4へ ↓ 質問4: フィルターで値が変わる? ├─ YES → メジャー ✓ └─ NO → 質問5へ ↓ 質問5: 文字列操作? ├─ YES → 計算列 ✓ └─ NO → メジャー(推奨)✓ 【黄金ルール】 迷ったらメジャー!
| 観点 | 計算列 | メジャー |
|---|---|---|
| 計算タイミング | データ更新時に1回 | 表示時に毎回 |
| 保存 | テーブルに保存 | 式のみ保存 |
| メモリ使用 | 多い(全行保存) | 少ない(式のみ) |
| 動的変化 | × 固定値 | ○ 動的 |
| スライサー | ○ 使える | × 使えない |
| 行・列(軸) | ○ 使える | × 使えない |
| 値 | ○ 使える | ○ 使える |
| 集計向き | × 不向き | ◎ 最適 |
| 行レベル計算 | ◎ 最適 | × 不向き |
| 推奨度 | 必要時のみ | 積極的に使用 |
| やりたいこと | 推奨 | 理由 |
|---|---|---|
| 売上の合計を表示 | メジャー | 集計は必ずメジャー |
| 年齢層でフィルター | 計算列 | スライサーで使うため |
| 利益率を表示 | メジャー | 動的な比率計算 |
| 姓と名を結合 | 計算列 | 行レベルの文字列操作 |
| 前年比を表示 | メジャー | 時系列の動的計算 |
| 顧客ランクで分類 | 計算列 | 分類&スライサー用 |
| 構成比を表示 | メジャー | 全体との比較が必要 |
💼 5. 実践的な使い分け例
良い例と悪い例で理解する
実際のシナリオで、計算列とメジャーの使い分けを見ていきましょう。
【NG例: 計算列で集計】 利益(列) = 売上[売上金額] - 売上[原価] 合計利益 = SUM(売上[利益(列)]) 問題点: ├─ 計算列で100万行を計算 ├─ メモリを無駄に消費 └─ データ更新が遅い ─────────────────────────────────── 【OK例: メジャーで直接集計】 合計利益 = SUM(売上[売上金額]) - SUM(売上[原価]) メリット: ├─ 計算列不要 ├─ メモリ効率的 ├─ 更新が速い └─ 同じ結果!
【計算列で顧客ランクを作成】
顧客ランク =
SWITCH(
TRUE(),
顧客[購入回数] >= 10, "プラチナ",
顧客[購入回数] >= 5, "ゴールド",
顧客[購入回数] >= 2, "シルバー",
"ブロンズ"
)
理由:
├─ 各顧客に固定のランク
├─ スライサーで使いたい
├─ ビジュアルの行に配置
└─ 計算列が適切!
使い方:
├─ 円グラフでランク別顧客数
├─ スライサーで「ゴールド」のみ表示
└─ テーブルで顧客一覧 × ランク
【メジャーで構成比を計算】
売上構成比(%) =
DIVIDE(
SUM(売上[金額]),
CALCULATE(
SUM(売上[金額]),
ALL(商品)
)
) * 100
動作:
├─ 商品Aを選択 → 商品Aの構成比
├─ 東京でフィルター → 東京内での構成比
└─ 動的に変化!
理由:
├─ 全体との比較が必要
├─ フィルターで値が変わる
├─ 計算列では不可能
└─ メジャーが適切!
【ステップ1: 計算列で年齢層を作成】
年齢層 =
SWITCH(
TRUE(),
顧客[年齢] < 20, "10代",
顧客[年齢] < 30, "20代",
顧客[年齢] < 40, "30代",
顧客[年齢] < 50, "40代",
"50代以上"
)
【ステップ2: メジャーで集計】
年齢層別売上 = SUM(売上[金額])
年齢層別顧客数 = DISTINCTCOUNT(売上[顧客ID])
【使い方】
├─ 棒グラフ: X軸=年齢層(列), Y軸=売上(メジャー)
├─ 円グラフ: 凡例=年齢層(列), 値=顧客数(メジャー)
└─ スライサー: 年齢層(列)で絞り込み
計算列とメジャーを組み合わせる!
⚠️ 6. よくある間違いと対策
初心者がやりがちなミス
計算列とメジャーの使い分けで、よくある間違いとその対策を紹介します。
| 間違い | 問題点 | 正しい方法 |
|---|---|---|
| 集計を計算列で作る | SUM等の集計関数は計算列で使えない(エラー) | メジャーで作成する |
| メジャーをスライサーに使う | メジャーはスライサーに配置できない | 計算列で分類を作成する |
| 行レベルをメジャーで計算 | 行ごとの値ではなく集計値が表示される | 計算列で作成する |
| 中間計算をすべて計算列に | メモリを大量に消費する | メジャー内で計算する |
【❌ 間違い】 合計売上(列) = SUM(売上[金額]) → エラー!計算列では集計関数が使えない 【✅ 正しい方法】 合計売上 = SUM(売上[金額]) → メジャーとして作成
【❌ 間違い: 3つの計算列を作成】
売上金額(列) = 売上[単価] * 売上[数量]
原価金額(列) = 売上[原価単価] * 売上[数量]
利益(列) = [売上金額(列)] - [原価金額(列)]
合計利益 = SUM(売上[利益(列)])
→ 3つの計算列でメモリ圧迫!
【✅ 正しい方法: メジャー1つで完結】
合計利益 =
SUMX(
売上,
(売上[単価] - 売上[原価単価]) * 売上[数量]
)
→ 計算列不要!
| 推奨事項 | 説明 |
|---|---|
| 計算列は最小限に | スライサー/分類のみに使用。集計には使わない |
| メジャーを積極的に | 集計は全部メジャー。迷ったらメジャー |
| 命名規則を決める | 計算列とメジャーを区別(例:列_年齢層、M_合計売上) |
| 不要な計算列は削除 | 使わなくなった計算列は削除してメモリを節約 |
| コメントを書く | 複雑な計算式には// でコメントを追加 |
📝 STEP 36 のまとめ
- 計算列:行レベル、テーブルに保存、スライサー可、メモリ消費大
- メジャー:集計レベル、式のみ保存、動的、メモリ効率的
- パフォーマンス:メジャーの方が圧倒的に効率的
- 使い分け:集計→メジャー、分類/スライサー→計算列
- 黄金ルール:迷ったらメジャー!
「集計はメジャー、分類は計算列」が基本です!
計算列を作る前に「これ、メジャーでできないかな?」と考える習慣をつけましょう。
99%の集計はメジャーで実現できます。
計算列は「スライサーで使いたい」「行ごとに値が必要」という明確な理由があるときだけ使いましょう!
📝 実践演習
以下はメジャーと計算列のどちらで作るべきか判断してください:
1. 全商品の合計売上
2. 顧客の年齢層(10代、20代など)
3. 売上の前年比
4. 商品カテゴリ(商品名から抽出)
| 項目 | 推奨 | 理由 |
|---|---|---|
| 1. 全商品の合計売上 | メジャー | 集計である、フィルターで変化する |
| 2. 顧客の年齢層 | 計算列 | 各顧客に固定値、スライサーで使いたい |
| 3. 売上の前年比 | メジャー | 時系列の集計、期間によって変化 |
| 4. 商品カテゴリ | 計算列 | 各商品に固定値、文字列操作、グループ化に使用 |
以下の計算列をメジャーに書き換えてください(可能なものだけ):
1. 利益(列) = 売上[売上金額] - 売上[原価]
2. フルネーム(列) = 顧客[姓] & 顧客[名]
3. 高額フラグ(列) = IF(売上[金額] > 10000, "高額", "通常")
| 項目 | 書き換え | 解説 |
|---|---|---|
| 1. 利益 | 可能(推奨) | 合計利益 = SUM(売上[売上金額]) - SUM(売上[原価]) 計算列は不要、メモリ節約 |
| 2. フルネーム | 不可 | 行レベルの文字列操作はメジャーでは困難。計算列のまま維持 |
| 3. 高額フラグ | 用途による | スライサー用→計算列のまま、集計だけ→メジャーに変換(高額注文数 = CALCULATE(COUNT(...), 売上[金額] > 10000)) |
100万行の売上データで、以下の2つの方法でメモリ使用量を比較してください:
方法A: 利益を計算列で作成してSUMする
方法B: 利益を直接メジャーで計算する
| 項目 | 方法A(計算列) | 方法B(メジャー) |
|---|---|---|
| DAX式 | 利益(列) = 売上金額 - 原価 合計利益 = SUM(利益(列)) |
合計利益 = SUM(売上金額) - SUM(原価) |
| メモリ(非圧縮) | 約8MB(100万行 × 8バイト) | 数KB(式のみ) |
| メモリ(圧縮後) | 約4-5MB | 数KB |
| データ更新時間 | 数秒(100万行計算) | 0秒(計算不要) |
| 効率性 | × | ◎(約1000倍効率的) |
結論:集計には絶対にメジャーを使うべき!大規模データほど差が顕著
❓ よくある質問
変更すべき計算列:
✓ 集計でしか使っていない
✓ スライサーやフィルターに使っていない
✓ ビジュアルの行・列に使っていない
変更手順:
1. メジャーで同じ計算を作成
2. ビジュアルを更新してテスト
3. 問題なければ計算列を削除
計算列が必須の場面:
✓ スライサーやフィルターとして使う(年齢層、カテゴリ分類など)
✓ ビジュアルの行・列として使う
✓ 文字列操作(名前の結合など)
✓ 複雑な行レベルの条件分岐
ただし「集計目的だけ」なら、計算列は不要です。
遅い場合のチェックポイント:
1. データモデルが最適化されているか(スタースキーマ)
2. リレーションシップが正しく設定されているか
3. 不要な列を削除しているか
4. CALCULATEの使い方が適切か
5. イテレーター関数(SUMX)を多用していないか
NG例:
売上合計(列) = 単価 × 数量
総売上 = SUM([売上合計(列)])
OK例:
総売上 = SUMX(売上, [単価] * [数量])
計算列は最終的に表示/フィルターする値だけに限定しましょう!
計算列:テーブルアイコン(Σなし)、テーブル内に表示
メジャー:電卓アイコン(Σあり)、テーブルの下に表示
命名規則を決めておくとさらにわかりやすくなります(例:M_合計売上、列_年齢層)。
SUM:SUM(売上[金額]) → 金額列の合計
SUMX:SUMX(売上, [単価] * [数量]) → 各行で単価×数量を計算し、その合計
SUMXはイテレーター関数と呼ばれ、行ごとの計算が必要な時に使います。ただし、大量の行で使うと遅くなる可能性があるため注意が必要です。
Power Query向き:
✓ 文字列の分割・結合
✓ データ型の変換
✓ 固定的な分類
✓ 列の追加・削除
計算列との違いは、Power Queryの方がデータモデルがシンプルになり、パフォーマンスも良くなることが多いです。
学習メモ
BIツール入門 - Step 36