なむなむ

@namb_nam による恥晒し

BigQueryのコスト削減メモ

見つけたので読む。

towardsdatascience.com

  • BigQueryにおけるlimit句は、メインのクエリ実行後に適用され、スキャン時間・コストを削減するためには使えない
  • スキャン時間・スキャンコストを削減するためには、joinwhere句を使う
  • テーブルの上位100けんならプレビューで見れる
  • UIのクエリ画面で、Ctrl押しながらテーブル名をクリックすると。スキーマ/詳細/プレビュー が見れる

  • exists 句ではselect *を使ってもよい

    • 以下の場合、select *でもselect 1でもスキャン量、実行時間は同じ。
select s.name 
from blog_perf.stations as s 
where exists
(
 select 1 --"select *" ではなく
 from blog_perf.rides as r
 where s.id = r.start_station_id
) 
  • SQL文の途中でorder byが発生すると、分散ノードからデータをマージした上でソートし、戻さなければならないので、パフォーマンスに影響する。
  • ソートする場合は最後に行う

  • 常に大きなテーブルから始め、where句で可能な限りフィルタリングしてから(できれば小さい)テーブルにジョインする

    • 分散アーキテクチャで必要なシャッフル量を大幅に削減できる
    • クエリオプティマイザーも上記を行おうとするが、念の為自分でも工夫する
    • クエリ①と②では、where句の対象が異なる。より大きなテーブルを対象にした②は、スキャン量が多くなってしまう。

クエリ①

select s.name,
       s.install_date,
       count(*) as ride_count
from blog_perf.rides r
 inner join blog_perf.stations s 
 on s.id = r.start_station_id 
where s.name like ‘%Park%’
group by 1,2

クエリ②

select s.name,
       s.install_date,
       count(*) as ride_count
from blog_perf.rides r
 inner join blog_perf.stations s 
 on s.id = r.start_station_id 
where r.start_station_name like ‘%Park%’
group by 1,2