なむなむ

@namb_nam による恥晒し

Linux ディレクトリと空ファイルを作成する

  • ディレクトリを作るのは mkdir
    • -p オプションをつけると、親ディレクトリも含めて作成する
    • mkdir -p dirA/dirB を実行すると、dirAが存在する場合はその配下にdirBを、dirAが存在しない場合はdirAとその配下のdirBを作成する
  • 空ファイルを作るのは touch
    • 本来は指定したファイルやディレクトリのタイムスタンプを変更するコマンドだが、存在しないファイルを指定したときは空の新規ファイルが作成される

データ処理言語の使い分け

『前処理大全』を読んでいる。

amzn.to

SQL・R・Pythonの特徴を活かした使い分け

前処理のフェーズの向き・不向き

  • データ構造を対象とした前処理 → SQL
  • レポーティングやアドホックな分析をするときの「データ内容を対象とした前処理」 → R
  • システム化するときの「データ内容を対象とした前処理」 → Python

処理による言語の向き・不向き

  • データサイズが大きいデータから抽出処理をするときはSQL
    • R/Pythonではメモリ上に展開できるデータサイズしか通常扱うことができない
  • データを縦持ちから横持ちに変換するときはR/Python
    • SQLでは長文を書く必要があるが、R/Pythonは1コマンドで実現可能
  • 前処理をシステム化するならSQLPython
    • システム化環境が充実しており、他システムとの連携も容易
  • 実行結果を記録しつつ分析作業を進めるアドホック分析の実現はR/Python
    • 容易なのはRだが、PythonもJupyterNotebookを用いれば実現可能
弊社の環境ではSQL in BigQuery + Pythonで、Rはほぼ使わない。
アドホック分析はBQのログを溜めていくか、Pythonでやるしかない。

そうか、縦横変換はPythonなら楽なのか...

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

BigQueryのクエリパフォーマンス最適化を学ぶ①

ベストプラクティスを学ぶシリーズ、どんどん続けていくぞ。

cloud.google.com

クエリパフォーマンスの概要

クエリパフォーマンスに影響する要素

  • 入力データとデータソース(I/O): クエリで何バイト読み取るか。
  • ノード間の通信(シャッフル): クエリから次の段階に何バイト転送するか。クエリは各スロットに何バイトずつ渡すか。
  • コンピューティング: クエリにはどのくらいの CPU 作業が必要か。
  • 出力(実体化): クエリは何バイト書き込むか。
  • クエリのアンチパターン: クエリは SQL のベスト プラクティスに従っているか。

チェック方法

クエリプランとタイムライン

  • BigQuery のクエリジョブには、診断で使用できるクエリプランとタイミング情報が埋め込まれる
    • 長期実行されるクエリの場合は定期的に更新される
  • 実行リソースを使用しないクエリジョブ(ドライランやキャッシュ利用)の場合は、他の統計情報が提供されるか、何もないかのいずれか

  • クエリアーキテクチャは動的である

    • クエリ実行中にクエリプランが変更される可能性がある
    • クエリ実行中に追加されるステージは、ワーカー全体にわたるデータ分散を向上させる
    • 変更されたクエリプランでは、ステージに”パーティション再設定ステージ”とラベルがつく
  • クエリ全体の進行状況を把握する際、実行のタイムラインを確認する

    • ワーカー内で完了・保留中_アクティブな作業単位の数が確認できる
    • クエリの複数ステージにアクティブワーカーが複数存在する場合がある

用語説明

  • 実行グラフ
  • クエリステージ

  • クエリプランの用語

    • 作業単位
    • ワーカー
    • スロット
      • コンピューティング、メモリ、I/O リソースなど、クエリの実行に必要な複数のファセットを抽象的に表す
      • ジョブ統計の概要では、この抽象的な単位に基づき、個々のクエリの totalSlotMs を表示