🙇‍♂️

Viewを使う上での大切な注意点(戒め)

2022/10/19に公開

前置き

こんにちは。株式会社GENDAのデータエンジニアのこみぃです。

皆さん、Viewって使ってますか?
私は便利に感じていて、結構多用しています。

今日はそんな中で非常に根本的なやらかしをしていたので、戒めとしてこの記事を書いています。

こういう恥ずかしいミスをしたという情報を開示することで今後の自分への戒めという名の術式を強めるということです。

黒歴史の開示。本気だね。

そして、当たり前のことですが、同じ轍を踏む人が少しでも減ることを祈っております。

今回のやらかしとViewの注意点

今回やらかしたのは非常に単純です。会社でのお話なんでそのまま記載はできないんですが、例を書きましょう。

まず、すごく大きなテーブルがあります。

sugoi_dekai_table

date user_id log_data その他たくさんの列
2022-10-01 101 login ・・・・・・
2022-10-01 101 add_cart ・・・・・・
2022-10-02 101 buy ・・・・・・
2022-10-02 102 login ・・・・・・

上には他にも色々カラムがついているとして、数千万とか数億とかの件数のレコードがあると思ってください。

そして、これらを集計するようなViewを作っているとしましょう。

sugoi_dekai_table_view

date user_id log_data
2022-10-01 101 login
2022-10-01 101 add_cart
2022-10-02 101 buy
2022-10-02 102 login

このViewに対して、特定の時期のデータを参照するようなselectを打つと、当然こういうSQLになりますね。

select_view
select * from sugoi_dekai_table_view where date >= '2022-07-01';

さて、このselectには実はすごくすごい問題があります。

というのも、SQLに置いてwhereによる絞り込みは早ければ早いほど処理が減ります。
↑のselectでは実際には以下のようなselectが発行されます。

select_table_through_view
with
omoi_tmp_table as (
    重い集計
    from
        sugoi_dekai_table
)
select
from
    omoi_tmp_table as
where
    date >= '2022-07-01'
;

しかし、このケースで本当に発行すべきなのは以下のようなクエリです

select_table_through_view
with
karui_tmp_table as (
    重い集計
    from
	sugoi_dekai_table
    where
        date >= '2022-07-01'
)
select
    *
from
    karui_tmp_table as
;

date >= '2022-07-01' の位置が違う感じですね。

このwhereの位置の違いはときに恐ろしいほどの性能差を生み出すことになります。
前者だと、まずテーブルを全部集計してから日付を絞ることになるからです。下手すると数年分のデータを毎回参照することになります。

私が今回やらかしたのは、概ねこういうことでした。かなC。

主な解決策

Viewを複数作る

用途に合わせてviewを作ってしまうというのが1つ目の解決策です。

特にデータを取得する用途がはっきりしている場合には、直近半年分のデータを取得するViewとか、そういうのを事前にいくつか作っておくことで用途に応じて使い分けることができます。

Viewは所詮はSQLのエイリアスなので、こういうのを手軽にやるのはやってもいいかなというところです。

マテリアライズド・ビューを使う

通常のViewはSQLのエイリアスなので前述したような挙動になりますが、マテリアライズド・ビューであれば話は違います。
マテリアライズド・ビューは実際にSQLを実施した結果を実態として保存しているので、参照しても元のテーブルには参照が行きません。

その分リフレッシュが必要とか色々面倒なことはありますが、方法の一つとして十分に検討に値すると思います。

そもそもViewを使わない

Viewを使うこと自体結構賛否両論ありますので、そもそも使わない運用にするというのも手かもしれません。
私も今後運用していて、最終的にViewは使わないほうがいいという結論になるかもしれません。

そこは今後の続報にご期待くださいというところで!!

本日の結論

本日のまとめは簡単ですね。

Viewを使うときはwhereの位置に気をつけろ!!

結びの言葉

そういうわけで、Viewは便利ですが、扱いに気をつけないといけないなというのを深く感じた出来事でした。
ただ、使わないうちに「Viewは使わないほうがいい!!」と決めつけたくはなかったので、しばらくは使っていこうと思っています。

最後に一つ宣伝を。
私が所属する株式会社GENDAでは一緒に働く仲間をすごく真剣に求めています。
興味がありましたらぜひお気軽にお声おかけください。
https://genda.jp/

本日はこのあたりで。
それじゃあ、バイバイ!

Discussion