Amazon Athena のパフォーマンスチューニングTips トップ 10ストレージのベストプラクティス1. データをパーティションに分ける2. ファイルを圧縮・分割する3. ファイルサイズを最適化する4. 列指向データの作成を最適化するクエリのベストプラクティス5. ORDER BY を最適化する6. JOIN を最適化する7. GROUP BY を最適化する8. LIKE 演算子を最適化する9. 近似関数を使う10. 必要なカラムだけを読み込む27 https://aws.amazon.com/jp/blogs/news/top-10-performance-tuning-tips-for-amazon-athena/
28.
データをパーティションに分ける• WHERE 句で頻繁に使われるカラムをパーティションキーに選ぶ•ログ等の場合は,日付が第一候補• テーブル内のパーティション数が増えすぎると,メタデータ取得・処理のオーバーヘッドが増える• データが特定パーティションに偏っている場合は,パフォーマンス状の恩恵を受けづらいクエリパーティション分けされていないテーブルパーティション分けされたテーブル実行時間 スキャン量 実行時間 スキャン量SELECT COUNT(*) FROM lineitemWHERE l_shipdate = ‘1996-’09-01’; 9.71s 74.1GB 2.16s 29.06MB
29.
データをパーティションに分ける• WHERE 句で頻繁に使われるカラムをパーティションキーに選ぶ•ログ等の場合は,日付が第一候補• テーブル内のパーティション数が増えすぎると,メタデータ取得・処理のオーバーヘッドが増える• データが特定パーティションに偏っている場合は,パフォーマンス状の恩恵を受けづらいクエリパーティション分けされていないテーブルパーティション分けされたテーブル実行時間 スキャン量 実行時間 スキャン量SELECT COUNT(*) FROM lineitemWHERE l_shipdate = ‘1996-’09-01’; 9.71s 74.1GB 2.16s 29.06MBSELECT count(*) FROM lineitem; 8.4s 74.1GB 10.65s 74.1GB
JOIN を最適化する31JOIN は大きなテーブルを左側に持ってくるほうがよい右側のテーブルを各ノードにBroadcast して JOIN するためPresto には Cost-based optimizer がないため,自動で最適化されない以下の例では,lineitem テーブル=7GB, part テーブル=67GBクエリ 実行時間SELECT count(*) FROM lineitem, partWHERE lineitem.l_partkey = part.p_partkey22.81sSELECT count(*) FROM part, lineitemWHERE lineitem.l_partkey = part.p_partkey10.71s
32.
ORDER BY を最適化する32集計クエリでORDER BY を行う場合,実際にはトップ100件くらいまでしか確認しないようなケースが多いORDER BY を行う際には,データを単一ノードに集約してソートするため,基本的に計算を並列化できないそのため,LIMIT 100 をつけてあげることで,ソート処理を高速に行うことができるSELECT*FROMlineitemORDER BYl_shipdateSELECT*FROMlineitemORDER BYl_shipdateLIMIT100
33.
GROUP BY を最適化する33GROUPBY に複数のカラムを指定する場合には,カーディナリティが高い順番に並べるほうがよい前に並んだカラムの値に応じて,各ノードにデータを割り振るため,カーディナリティが低いデータだと,処理が十分に並列化されないFROMaction_logGROUP BYlow_card_col, high_card_colFROMaction_logGROUP BYhigh_card_col, low_card_col
34.
LIKE 演算子を最適化する34LIKE 演算子で多数の比較を行う場合には,RegExで一括処理をしたほうが効率がよいそれぞれの LIKE 演算子について捜査が走るため,数が増えるほど,また文字列が長くなるほど,処理が重くなるWHEREcomment LIKE ‘%wake%’, comment LIKE ‘%regular%’, comment LIKE ‘%expres%’, comment LIKE ‘%sleep%’, comment LIKE ‘%hello%’WHEREregexp_like(comment, 'wake|regular|express|sleep|hello')