tableauを扱う際に、重くならないために新人が意識すべきこと

tableauの研修として「Data Saber」という団体が運営する、tableau育成プログラムに参加しています。
データを扱うものとして、tableauの技術だけではなく、どのように見せるのが読者にとって最適なのかという問いを、常に自分にかしながら身につけられるプログラムになっています。
今回はそんな新人が現場に入る前に、tableauの動作が遅くならないように最低限覚えておくと良さそうなリストを集めてみましたので、参考にしてみてください。

## 計測方法
エンジニアをしていた頃もフロントエンドを中心に関わっていましたので、ECサイトなどではCore Web Vitalsの指標など会社としても重視していて、よくSpeed Insightsにはお世話になっておりました。
そんなふうにtableauのパフォーマンスを計測する方法が実はありますので、新人のうちは度々自分が作成したtableuのバフォーマンスをチェックすると良いと思います。
徐々に意識して作成することが、チリが積もっていくと思われます。
チェック方法は下記の記事が参考になります。

https://ex-ture.com/blog/2020/05/21/why-your-tableau-heavy/

## 基本知識

### Tableauのダッシュボードを速くするための基本は、データの接続方法を「ライブ」接続ではなく「抽出」にすること

「ライブ」接続にしなければいけない要件は主に2つ。

1.リアルタイムのデータを表示する必要がある時
2.扱うデータ量が多すぎて抽出ができない時

この2点にあてはまらない場合は「抽出」に切り替え

逆に、「2. 扱うデータ量が多すぎて抽出ができない時」に当てはまる場合は、今一度設計を見直してみるのがいい。

・抽出のレコードの限界の目安としては1億レコード
・3000万レコードを超える場合は、設計時からパフォーマンスを意識する必要がある
・500万レコード以下はたいていは速く表示可能

### ・小さいデータ型を使用する。

パフォーマンスで考えるとTableauのデータ型は以下の順で使用すべき。
「ブール値 > 整数 > 浮動小数点数 > 日付 > 日付と時刻 > 文字列」

まずはデータソースを設計する場合に、以下の観点で見直せないかを検討します。

#### ・NULL以外に値が2種類しかないカラムがないか
検討する上でのポイントは、「今後データが増えた時にも2種類以上に増えることがないか」 です。
2種類以上に増える可能性がある場合は、整数型で代用できないかを検討した方がいいです。データ型の変更は、影響が大きくなりがちなので今後のデータの増え方も検討すべきです。

ブール値型にする場合は、Trueにどちらの値を設定するかは

・フィルターでよく利用する値
・計算フィールドで利用する値
など判定条件が = True になるように値を決めるのが望ましいです。
これは、設計上の経験が必要ですので迷った場合は、2種類の中でレコード数の多い値をTrueにした方がうまくいきます。

#### ・小数の列を整数のデータ型として持つことはできないか

小数のデータで小数点以下の桁数がどの値も決まっている場合は、整数型に検討できる可能性があります。

例えばパーセント表記するために持っている値は、
「小数型で表示形式を%にする」→「整数型で表示形式で%を後ろにつける」
とすることでうまくいくことがあります。

また整数型にできない場合でも、Tableau上では四捨五入して表示する場合にはデータソースでは厳密な値を持たずに事前に小数第●位までに丸めておくことも、パフォーマンス上いいアイデアです。

#### ・日時データを日付型 または 日付型 と 整数型のカラムに分けて持つことができないか

元のデータソースでは日時データ型になっているが、入っているデータは全て日付までで時間の部分が00:00:00 になっていることはありませんか？

これは、日時型を日付型に変えるべき典型的なケースですが、それ以外でも日時型の使用を避けるケースは多くあります。

ダッシュボードでは、実際に秒まで表示することは少なく、時間や分まででまとめられていることが多いと思います。秒まで必要ない場合は、時間や分の整数型のカラムを別途用意して事前にその単位にデータを集計しておくと、パフォーマンスを向上させることができます。

#### ・文字列型のデータは値の種類が限られているので、別名を活用して整数型に置き換えられないか？

文字列型はパフォーマンスを悪くする大きな原因の1つです。そのため値の種類が限られている場合は、データをコード値と呼ばれる整数の値に置き換えて、Tableauの「別名」機能を利用して表示時に文字列に置き換えることでパフォーマンスがアップします。

今後、値の種類が増える可能性がある場合は、「別名」の形にするとTableauの再パブリッシュといったメンテナンスが必要になります。めったに変わらない場合は、「別名」の利用すべきですが頻繁に追加される場合は、文字列のデータをデータソース上に持つ必要があります。

「別名」が利用できない場合でも、コード値の整数型のデータを作成することで、パフォーマンスが向上するケースがありますので、そちらは別で記事にしたいと思います。

### ・パラメータのデータ型

パラメータの設定で許容値を「リスト」として使う場合は、データ型を小さくすることができるかもしれません。

・リストが2つしかない場合：「ブール値型」
・リストが3つ以上：「整数型」

文字列になりそうな場合もリストの表示名で別名を設定すれば代用可能です。

### ・ネイティブ機能の活用
・項目のグルーピングは、計算フィールドを使わず「グループ」機能を利用する。

・項目の結合は、計算フィールドで結合せずに、「結合済みフィールド」機能を利用する。

・計算フィールドを使わず、プレフィックスやサフィックスなど書式設定を活用する。

### ・計算フィールド
・計算フィールドを使わず事前にDBで計算できないかを検討する。

・計算フィールド内での計算フィールドの参照を避ける。
パフォーマンスを優先するならば、1つの計算フィールドにまとめることも検討すべき。

・計算を簡略化できないかを検討
表計算などを利用する場合に、生成された数式を確認して簡略化できないかを検討する。

・計算フィールドでのセットやグループの使用を避ける
CASE WHEN なので代用する

### ・条件分岐
・ELSE IF より ELSEIFを利用
Tableauの作り上、 ELSEIFは分割せずに1フレーズで利用した方が速い

・CASE WHEN で代用できる場合はこちらを利用（IFのネストは避ける）
特に計算フィールドを使っている場合は、IF文では複数回計算フィールドを参照されるところを、CASE文で1回にすることが可能な場合あり

・IFをネストする場合は、データから判定回数が減るように順番を検討する。
判定回数が減るように、データセットを確認しながらIF文のネストの順番は検討した方がよい。

### ・関数
・日付の場合、NOW()よりTODAY()を使う
NOW()は時間まで取得するので、日付のみを利用する場合は、TODAY()の方がよい。

・集計関数 MIN, MAX, SUMは速い。 AVGは遅い。COUNTDはさらに遅い。
ATTRは、MINかMAXで代用する。その他の集計関数の使用は多用しない。

・文字列関数（LEFT,MID,RIGHT）もパフォーマンスが悪いので、使用回数を少なくする。

### ・LOD表現
・LODも遅いので、使用箇所は要検討
LOD関数によりデータセットを何度も集計することになるので、使いどころは要検討。一方で、LOD関数を利用することでデータセット自体を小さくすることができる場合もあるので、全体としてパフォーマンスが向上することもある。

・LODよりも表計算を利用する
LODよりも表計算の方が速いことがある。細かいチューニングをする場合は、パフォーマンスをモニタリングして、どちらの実装が速いかを検討すべき。

・EXCLUDEよりINCLUDEの方がパフォーマンスがよい。

### ・形状
・形状にカスタムシェイプの使用を避ける

・カスタムシェイプの画像は大きいサイズにしない

### ・フィルター
・除外フィルターはパフォーマンスが悪い
連続の範囲指定フィルターで代用できないかを検討

・不連続の項目より連続項目のフィルターの方が速い
リスト選択型のフィルターより範囲指定のフィルターの方が速い

・フィルターの適用範囲は必要最低限にする
むやみにフィルター項目を追加しない。

・ユーザフィルターはキャッシュが効きにくいので使用を避ける
ユーザフィルターはデータ量も増えやすいので、利用する場合は注して設計を行う必要があある

・範囲指定のクイックフィルターの方がパフォーマンスがよい
不連続の項目のリストから連続の範囲フィルターにできないかを検討する

・データソースフィルターは使用しない
データソースフィルターでフィルタリングするより、SQLの段階でフィルタリングする方がパフォーマンスがよい

### ・コンテキストフィルター
。コンテキストフィルターは設定する場合も1シート1フィルター
コンテキストフィルターを設定すればパフォーマンスが必ず良くなるわけではなく悪化する場合も多い。1つのみ設定して、前後で体感レベルで向上しているかを確認する

・FIXEDのフィルターとしてのコンテキストフィルターを利用することは有効

・関連値の代わりとしてのコンテキストフィルターを利用することもあり

### ・クイックフィルター
・関連値のみの使用もパフォーマンスが悪い
関連値はフィルターを変更する度にクエリが発行されるので、使用は最低限にする

・クイックフィルターの数は少なくする
多数のクイックフィルターがどうしても必要な場合は、フィルター用のダッシュボードにすることも検討する。

・項目数の多いクイックフィルターは避ける
項目数の多いフィルターは表示に時間がかかる。ワークシートをフィルターとして使うような多段階の絞込み方法などの代用も検討すべき

・フィルターが重い場合は、「適用ボタン」の利用も検討する。
操作性は悪くなるので、安易には採用しないでその他のチューニング方法をまずは検討する。

・アクションフィルターの多用は避ける。

### ・ダッシュボード・シート
・表示モードは固定にする
キャッシュが効きやすくなる。自動調整のレイアウトの場合はフィルター項目が同じでも画面サイズが異なるとキャッシュが効かない。

・使用していないシートはダッシュボードから削除する
使用していなくても計算処理が走るので、ダッシュボードから削除する。

・シートの数を増やすと遅くなるので要注意
1ダッシュボード 3,4シートが目安。

・集計表は大きくなると遅くなるので注意
Tableauで巨大な集計表の表示には時間がかかる。上位〇〇件といったフィルターをかけられないかという仕様の検討をすべき

・シートのマーク数は確認
数が多いと遅くなるので注意。各シートの左下のマークの数値を確認して、無駄なものがないかをチェックする

・1ワークブックに含まれるダッシュボード数が増えると初期表示が重くなる
場合によってはワークブックを分けることを検討すべき。

・タイルで配置するか、浮動で配置するかはパフォーマンスに大きな違いはない。

## まとめ

上記はtableauの動作が重くなった際に個人的なチェックシートのような役割で使おうと思っています。
ぜひ皆さんも参考にしてみてください。