分析クエリの最適化
1)最適化する理由(iGamingコンテキスト)
ビジネスのスピード:p95 SLAのGGR/NETレポート、プロバイダー/ゲーム、RG/AMLおよびマーケティング。
コスト:より少ないスキャンされたバイトとshafl→$/request以下。
信頼性:安定したピーク時間、BIは凍りません。
スケール:ブランド/市場の数十、ラインの数十億、鮮度の分。
2)負荷プロフィールおよびSLO
要求の「最初の90%」: windows (7/28/90d)、フィルタ('brand、 country、 provider、 psp、 status')、 join's、 JSON属性、top Kおよびpercentiles。
SLOの例:p95 ≤ 1。ダッシュボード、スキャンされたバイト≤ 256 MB/リクエスト、鮮度≤ 5分。
3)計画の解剖学: 何を探すべきか
Predict/Projectionプッシュダウン-フィルタと列リストはソースには省略されます。
パーティションプルーニング&データスキップ(min-max/bloom/manifest)。
Vectorized scan/late materialization:列はJOIN/PROJECTによって遅延されます。
参加戦略:ブロードキャストハッシュ(BHJ)、ソートマージ(SMJ)、ネストされたループ(NLJ-избегать)。
こぼれ&シャッフル:シャッフルとディスクへのこぼれのボリュームは、SLAの主な敵です。
適応クエリ実行:実行時の戦略の変更(BHJ↔SMJスイッチング、ダイナミックコアレス)。
プランは次のように表示する必要があります。私たちが読んだバイト数、シャフリムの場所、キャッシュするもの。
4)当事者、分類、クラスターケース
パーティー:'date'+1-2アクセス寸法(例:'brand、 country')。
並べ替え/クラスタリング:'ORDER BY/CLUSTER BY/Z-order' ('provider、 game_id、 occurred_at')。
再分類および圧縮:データのスキップのための規則的な移動;ターゲットファイルサイズは128-1024 MBです。
5) JOINパターン
ブロードキャストハッシュジョイン(BHJ):小さな寸法(数百MBを≤)→事実にブロードキャスト。
sql
/ hint if engine supports/
SELECT /+ BROADCAST(dim_provider) /...
Sort-Merge Join (SMJ):大きなセット、互換性のあるキーのソート/クラスターケース→最小シャフト。
Pre-join/denormalization:安定した属性を'dim _'から実際のスナップショット(投影/実体化ビュー)に移動します。
Anti/semijoins: 'NOT IN/EXISTS'を明示的なセミジョンプラン/アンチジョインプランに書き換えます。
基本爆発の排除:重複したキーを寸法でチェックし、サロゲートキーを使用します。
6)グループ化、集計、事前集計
ロールアップ/キューブ/グループ化セット:複数の集計の代わりに1つのフェーズ。
sql
SELECT brand, country, DATE(ts) d, SUM(amount)
FROM gold. payments
WHERE ts >= NOW() - INTERVAL '7 days'
GROUP BY GROUPING SETS ((brand,country,d),(brand,d),(d));
マテリアライズドビュー(MV)/投影:'payments_7d_by_brand_psp'、 'rounds_1d_by_provider_game'。
Partial→Final Aggregation:エンジンがワーカー(ローカル)と最後にコーディネーターに部分的に集約できるようにします。
おおよその値:'COUNT (DISTINCT user)'のHLL、パーセンタイルのTDigest-BIのための複数の安価で十分。
7)窓の機能(端正な)
高い選択性のキーの丁度パーティション;ORDER BY-列の並べ替えによる。
可能であれば、重いウィンドウを事前集計とセミジョインに置き換えます。
sql
-- Instead of window distinct
SELECT brand, COUNT() users
FROM (SELECT DISTINCT brand, user_id FROM gold. sessions WHERE d>=CURRENT_DATE-7) t
GROUP BY brand;
8)フィルター、paginationおよびTOP-K
フィルタ順序はCBOにとって重要ではありませんが、選択性とインデックス/ソートがあります。
LIMIT……WITH TIES/APPROX TOP-K-スキャンを短縮します。
ページネーション:大きなテーブルの'OFFSET/LIMIT'の代わりに'keyset pagination'。
sql
-- keyset
SELECT FROM t WHERE (date, id) > (:last_date,:last_id) ORDER BY date, id LIMIT 1000;
9) JSON/半構造化
ホットパスを列('device。os'、'psp。method')。
エンジンがサポートしている場合は、JSONパスで反転/GINインデックスを使用します。
行ごとにUDFを避ける:ハイライトされた属性を持つより良い投影。
10)およそおよびサンプリング
HLL/Theta Sketch:安価な'COUNT DISTINCT'。
TDigest/KLL:完全な並べ替えなしでp95/p99パーセンタイル。
リザーバ/層別サンプリング:インタラクティブな研究とプレビュー。
11)記憶、海峡およびConcarrency
こぼれ監視:結合/aggの記憶限界;こぼれるとき-バッチ/並列性を減らして下さい、キーによって分類を高めて下さい。
並行性及びQoS:「熱い」ダッシュボードおよび重い地獄hocのためのプール;スキャン/時間制限;kill-switchを「忘れた」リクエストに切り替えます。
結果キャッシュ/クエリキャッシュ:再現可能なBIテンプレートを有効にし、鮮度トークンで無効にします。
12)回帰テストと「ダブルラン」
トップNクエリの参照プロファイル(plan/scan bytes/time)を保存します。
インデックス/クラスタをリリースする前に-A/B実行:p95、スキャンされたバイト、スキップされた共有、シャッフルを比較します。
"fail-fast'しきい値を作成:p95 rose> X%-ロールバック。
13)観察可能性およびSLO
SLI:- p50/p95/p99レイテンシ、スキャンされたバイト/クエリ、スキップされたバイト%、タッチされたファイル;
- シャッフルバイト、こぼれたバイト、ピークメモリ;
- キャッシュヒットレート;正確さのアプローチ集計。
アラート:スキャンされたバイト数の増加、スキップされたシェアの低下、頻繁なNLJ、 spillage>しきい値。
14) iGamingケース(レシピ)
14.1支払い/PSP:「放棄のピーク」
WHERE: 'ts BETWEEN()-7d AND now()'、'brand、 country、 psp、 status'。
パーティー: 日;ORDER/Z-order:'(ブランド、国、ts)';ビットマップ:'psp、 status';bloom: 'transaction_id'
MV: 'payments_7d_by_brand_psp (status)'。
結果:p95→~ 1s、スキャンされたバイト数:5-10 ×、ゼロ海峡。
14.2ゲームラウンド:トップKゲーム/時間
ORDER BY/cluster '(provider、 game_id、 occurred_at)';事前集計のための投影。
p95ラウンド期間の約Top-K+TDigest。
ボトムライン:ホットキャッシュの2番目のグラフ。
14.3 RG/AMLアクティブリミット
JSON 'reason'→列;ビットマップ'rg_state'、 'kyc_level';最後の状態との半加入。
結果:レポート「30日間」-秒、フルスキャンなし。
15)最適化チェックリスト(毎日)
1.トップNリクエストとそのプロファイル(plan/bytes/shafl)のコレクション。
2.日付によるバッチ+合意されたソート/クラスタケース。
3.プッシュダウンと投影剪定のチェック(必要な列のみ)。
4.JOIN戦略:SMJ、 No NLJのためのスモールブロードキャスト、ソート。
5.ホットダッシュボード用の事前集計/MV。
6.約有効な場合(区別/パーセンタイル/top-k)。
7.JSON→カラムおよび/または反転インデックス。
8.圧縮/再分類;スキップされたバイトのターゲット≥ 70%です。
9.結果キャッシュと個別のconcarrencyプール。
10.モニタリング:p95、スキャンされたバイト、シャッフル、こぼれ、ヒットレート。
16)テンプレート(使用可能)
16.1最適化ポリシー(YAML)
yaml workload: bi_hot slo:
p95_latency_ms: 1200 scanned_bytes_max_mb: 256 skipped_bytes_share_min: 0. 70 storage:
partition_by: ["date"]
cluster_by: ["brand","country","occurred_at"]
indexes:
bloom: ["transaction_id","user_surrogate_id"]
bitmap: ["psp","status","rg_state"]
aggregation:
mv:
- name: mv_payments_7d_brand_psp window: "7d"
group_by: ["brand","psp","status"]
approx:
count_distinct: "hll"
percentile: "tdigest"
concurrency:
pools: {bi_hot: 50, adhoc: 10}
timeout_s: 120
16.2クエリ回帰テスト(疑似SQL)
sql
-- baseline: p95<=1200ms, scanned_bytes<=256MB
EXPLAIN ANALYZE
SELECT brand, psp, status, COUNT() cnt, SUM(amount) amt
FROM gold. payments
WHERE ts >= NOW() - INTERVAL '7 days'
AND brand =:brand AND country =:country
GROUP BY brand, psp, status;
16.3 DISTINATE書き換え
sql
-- Bad: Heavy COUNT (DISTINCT user_id)
SELECT COUNT(DISTINCT user_id) FROM gold. sessions WHERE d>=CURRENT_DATE-7;
-- Better: HLL sketch/preaggregate
SELECT hll_union(user_hll) FROM agg. sessions_7d_user_hll WHERE d>=CURRENT_DATE-7;
16.4キーセットページネーション
sql
SELECT
FROM gold. game_rounds
WHERE (occurred_at, round_id) > (:ts,:rid)
AND brand=:brand AND country=:country
ORDER BY occurred_at, round_id
LIMIT 1000;
17)アンチパターン
prodの'SELECT';投影剪定の欠如。
オフセット数百万行のページネーション。
スケッチなしでDISTINCTを数えて下さい;完全な並べ替えによるパーセンタイル。
大きいセットのNLJ;JSON式で結合します。
小さなバッチと散乱ファイル(メタデータ嵐)。
列を具現化する代わりに、WHEREのUDF文字列。
統計/分析を無視-ブラインドオプティマイザとフルスキャン。
回帰テストもロールバックしきい値もありません。
18)実装ロードマップ
0-30日(MVP)
1.トップNリクエストの測定とSLO/SLIの設置。
2.日付によるバッチ+並べ替え/クラスターケース;データのスキップ/ブルームを有効にします。
3.熱い支払のレポートごとの1つのMV;HLL/TDigest-BI。
4.クエリプールを分割し、結果キャッシュを有効にします。
30-90日
1.重いウィンドウの国勢調査/JSON→事前集計/列。
2.放送結合の小さい次元;大きいのためのSMJ;NLJの排除。
3.コンパクト化と再分類のスケジュール;キーアドバイザー。
4.劣化の観測性とアラート、A/B計画、自動ロールバック。
3〜6ヶ月
1.バージョニングとSLAを備えたプロジェクション/MVカタログ。
2.すべてのダッシュボードで/percentile/top-kを区別するための約カーネル。
3.回帰テストと予算$/リクエストのためのユニフォームテンプレート。
4.JSONとUDFの永久衛生:具現化とインデックス。
19) RACI
データプラットフォーム(R):パーティション/クラスタリング/圧縮、MV/投影、キャッシュ、監視。
分析/BI (R): SQLの書き換え、約集計、回帰テスト。
ドメイン所有者(C):セクションと精度の要件。
セキュリティ/DPO (A/R): privacy/PII、 k-anonymity of aggregates。
SRE/Observability (C): SLO/アラート、 concarrencyおよび容量。
財務(C):$/要求と経済効果のための予算。
20)関連セクション
分析ストレージインデックス、データスキーマと進化、データ検証、DataOpsプラクティス、データクラスタリング、ディメンションリダクション、アナリティクスとメトリクスAPI、 MLOps:モデル開発。
合計
クエリの最適化は「マジックヒント」ではなく、有能なデータマークアップ(パーティション/クラスタ)、事前集計とおおよそのアルゴリズム、正しいJOIN戦略、p95とスキャンされたバイトのキャッシュ/concarrencyと一定の監視です。iGamingの場合、これは支払い、ゲーム、コンプライアンスのための迅速かつ安定した指標を意味します。