Athenaのパーティション項目の型とパーティションプロジェクションの奇妙な関係
Athenaのパーティションプロジェクションを試していたらちょっとハマったのでメモしておく
追記(2021/03/23)
projection.columnName.digitsを設定すれば パターン1でもきちんと検索できる
パターン1
S3には /app_log/year=2020/month=06/day=05/hour=04/
のような場所にログをおいている
year, month, day, hourを Glueテーブル上の型で stringにする
パーティションプロジェクション上の型はintegerにする(stringがないので)
たとえば projection.month.type = "integer"
SELECT * FROM my_db.app_log WHERE year = '2020' AND month = '06' AND day = '05' AND hour = '04' LIMIT 10
のように検索するとヒットする。 しかし
SELECT * FROM my_db.app_log WHERE year = '2020' AND month = '06' LIMIT 10
はヒットしない!
パターン2
S3には /app_log/year=2020/month=06/day=05/hour=04/
のような場所にログをおいている
year, month, day, hourを Glueテーブル上の型で intにする。
パーティションプロジェクション上の型はintegerにする(stringがないので)
たとえば projection.month.type = "integer"
SELECT * FROM my_db.app_log WHERE year = 2020 AND month = 6 AND day = 5 AND hour = 4 LIMIT 10
のように検索するとヒットしない!
SELECT * FROM my_db.app_log WHERE year = '2020' AND month = '06' AND day = '05' AND hour = '04' LIMIT 10
のように検索してもヒットしない!
パターン3
S3には /app_log/year=2020/month=6/day=5/hour=4/
のような場所にログをおく。つまり 0 を抜いた
year, month, day, hourを Glueテーブル上の型で intにする
パーティションプロジェクション上の型はintegerにする
たとえば projection.month.type = "integer"
SELECT * FROM my_db.app_log WHERE year = 2020 AND month = 6 AND day = 5 AND hour = 4 LIMIT 10
のように検索するとヒットする
SELECT * FROM my_db.app_log WHERE year = 2020 AND month = 6 LIMIT 10
もヒットする。
つまり、S3のパーティションにあたる値が0がついていない数値でかつ、 Glueテーブルとパーティションプロジェクションの型が数値型でないといけない!!
じゃあ S3の ディレクトリを /app_log/year=2020/month=06/day=05/hour=04/
から
/app_log/year=2020/month=6/day=5/hour=4/
に変更しようとしても、0抜き指定はfluentdのオプション上できない。https://docs.fluentd.org/v/0.12/output/file#time_slice_format
※追記
よくよく考えると、もしfluentdがTime#strftimeを使っているなら
year=%Y/month=%-m/day=%-d/hour=%-H
で0抜きができそう。
パターン4
S3には /app_log/dt=2020-06-05-04/
のような場所にログをおく 。
dt=YYYY-mm-dd-HHのような形式は
https://docs.aws.amazon.com/athena/latest/ug/partitions.html でも記されているので公式に近い。
dtを Glueテーブル上の型で stringにする
パーティションプロジェクション上の型はdateにする。 projection.dt.type = "date"
SELECT * FROM my_db.app_log WHERE dt > '2020-06-05-04' LIMIT 10
のように検索するとヒットする
SELECT * FROM my_db.app_log WHERE dt > '2020-06' LIMIT 10
でもヒットする
まとめ
パターン4が妥当かな