3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Tableauのカスタム分割(split関数)は使用しない方がいいかも

Last updated at Posted at 2020-07-23

Tableauで文字列を分割する場合、よく用いられるのがカスタム分割です。区切り文字と、何列目を取得するかを指定すると自動で文字列が取得できる優れものです。以下がその設定画面です。

image.png

結論から言うと、シンプルな方法で文字列を取得できるのであれば、カスタム分割を使わない方がパフォーマンスが向上する可能性が高いです。

まずカスタム分割がどのように動作しているかを検証してみます。今回は以下のようなオーダー IDの列に対して実行してみます。データソースはSQL Serverです。
image.png

「-」(ハイフン)で区切り、3列目を取得するように指定すると、以下のような計算フィールドが生成されます。
image.png

このSPLIT関数の動作を確認します。以下のメニューからパフォーマンスの記録を実行します。

 ヘルプ -> 設定とパフォーマンス -> パフォーマンスの記録を開始

この状態でカスタム分割の計算フィールドをシェルフに入れるなどして少し操作し、DBにクエリを発行させます。その後、停止します。

 ヘルプ -> 設定とパフォーマンス -> パフォーマンスの記録を停止

Executing Queryをクリックし、SPLIT関数をどのようなクエリで実現しているのか確認します。

image.png

凄く長いカオスな式が出てきます。SPLIT関数を汎用的にするため例外処理なども入っているためか、複雑になっています。LTRIM(RTRIM())はTRIMに対応する部分だと思いますので、その中がSPLIT関数に対応する部分になります。

LTRIM(RTRIM((CASE WHEN ([注文].[オーダー ID] IS NULL) THEN CAST(NULL AS NVARCHAR) WHEN NOT ([注文].[オーダー ID] IS NULL) THEN ISNULL((CASE WHEN CHARINDEX('-',[注文].[オーダー ID],cast((CASE WHEN CHARINDEX('-',[注文].[オーダー ID])= 0 THEN LEN([注文].[オーダー ID])+ 1 WHEN NOT CHARINDEX('-',[注文].[オーダー ID])= 0 THEN CHARINDEX('-',[注文].[オーダー ID])+ 1 ELSE NULL END) as int))= 0 THEN '' WHEN NOT CHARINDEX('-',[注文].[オーダー ID],cast((CASE WHEN CHARINDEX('-',[注文].[オーダー ID])= 0 THEN LEN([注文].[オーダー ID])+ 1 WHEN NOT CHARINDEX('-',[注文].[オーダー ID])= 0 THEN CHARINDEX('-',[注文].[オーダー ID])+ 1 ELSE NULL END) as int))= 0 THEN (CASE WHEN CHARINDEX('-',SUBSTRING([注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID])+ 1 as int))+ 1 as int),LEN([注文].[オーダー ID])))= 0 THEN SUBSTRING([注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID])+ 1 as int))+ 1 as int),LEN([注文].[オーダー ID])) WHEN NOT CHARINDEX('-',SUBSTRING([注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID])+ 1 as int))+ 1 as int),LEN([注文].[オーダー ID])))= 0 THEN LEFT(SUBSTRING([注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID])+ 1 as int))+ 1 as int),LEN([注文].[オーダー ID])),(CASE WHEN CHARINDEX('-',SUBSTRING([注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID])+ 1 as int))+ 1 as int),LEN([注文].[オーダー ID])))- 1 >= 0 THEN CHARINDEX('-',SUBSTRING([注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID],cast(CHARINDEX('-',[注文].[オーダー ID])+ 1 as int))+ 1 as int),LEN([注文].[オーダー ID])))- 1 ELSE NULL END)) ELSE NULL END) ELSE NULL END), '') ELSE NULL END)))

これを大量の行に対して実行する場合、この計算のために処理が遅くなる可能性があります。スポット的な分析ではなく、継続利用するダッシュボードで使う場合などは使用を避けたがいいかもしれません。

例えばこのSPLIT関数をMID関数に書き換えると、以下のようにシンプルなクエリが実行されます。

SUBSTRING([注文].[オーダー ID],cast(9 as int),LEN([注文].[オーダー ID]))

なお、複雑なクエリとなるのはSQL Server等のDBをデータソースとする場合で、Excelのデータに対して実行する場合などはクエリを使わないので、カスタム分割の方が適している可能性があります。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?