EMR-Presto 和 Athena 的查询结果差异

Posted

技术标签:

【中文标题】EMR-Presto 和 Athena 的查询结果差异【英文标题】:Query results difference between EMR-Presto and Athena 【发布时间】:2018-09-16 09:46:15 【问题描述】:

我已将 Glue 目录连接到 Athena 和一个 EMR 实例(安装了 presto)。我尝试在两者上运行相同的查询,但得到不同的结果。 EMR 给出 0 行,但 Athena 给出 43 行。使用left joingroup bycount distinct,查询非常简单。查询如下所示:

select
  t1.customer_id as id,
  t2.purchase_date as purchase_date,
  count(distinct t1.purchase_id) as item_count
from 
  table1 t1
left join
  table2 as t2
  on t2.purchase_id=t1.purchase_id
where 
  t1.item_type='ABC' 
  and t1.purchase_status='CONFIRMED' 
  and t1.region_id in ('A','B','C')
  and t2.status='Dispatched'
  and t2.purchase_date between date_add('day',-50,date('2018-09-13')) and date('2018-09-13')
  and t1.created_at between date_add('day',-60,date('2018-09-13')) and date('2018-09-13')
  and t1.updated_at between date_add('day',-60,date('2018-09-13')) and date('2018-09-13')
group by
  t1.customer_id,t2.purchase_date;

我尝试了其他一些查询,但结果完全匹配。不知道这个查询有什么问题。

EMR Version: 5.17.0
Presto Version: 0.206

编辑:我意识到问题出在第一个表本身。由于某种原因,Presto-EMR 无法在 table1 中找到任何行。不知道为什么会发生这种情况,因为 Presto-EMR 和 Athena 都使用相同的 Glue 目录。我还在同一个 EMR 实例中尝试了 Hive,它能够在 table1 中找到行。

select * from table1 limit 10;

上面的语句用 hive-sql 给出 10 行,但用 presto-sql 给出零行。我在调试模式下看到以下异常:

Query 20180917_075536_00023_4988g failed: com.facebook.presto.spi.type.TimestampType
java.lang.UnsupportedOperationException: com.facebook.presto.spi.type.TimestampType
    at com.facebook.presto.spi.type.AbstractType.writeSlice(AbstractType.java:135)
    at com.facebook.presto.hive.parquet.reader.ParquetBinaryColumnReader.readValue(ParquetBinaryColumnReader.java:55)
    at com.facebook.presto.hive.parquet.reader.ParquetPrimitiveColumnReader.lambda$readValues$1(ParquetPrimitiveColumnReader.java:184)
    at com.facebook.presto.hive.parquet.reader.ParquetPrimitiveColumnReader.processValues(ParquetPrimitiveColumnReader.java:204)
    at com.facebook.presto.hive.parquet.reader.ParquetPrimitiveColumnReader.readValues(ParquetPrimitiveColumnReader.java:183)
    at com.facebook.presto.hive.parquet.reader.ParquetPrimitiveColumnReader.readPrimitive(ParquetPrimitiveColumnReader.java:171)
    at com.facebook.presto.hive.parquet.reader.ParquetReader.readPrimitive(ParquetReader.java:208)
    at com.facebook.presto.hive.parquet.reader.ParquetReader.readColumnChunk(ParquetReader.java:258)
    at com.facebook.presto.hive.parquet.reader.ParquetReader.readBlock(ParquetReader.java:241)
    at com.facebook.presto.hive.parquet.ParquetPageSource$ParquetBlockLoader.load(ParquetPageSource.java:244)
    at com.facebook.presto.hive.parquet.ParquetPageSource$ParquetBlockLoader.load(ParquetPageSource.java:222)
    at com.facebook.presto.spi.block.LazyBlock.assureLoaded(LazyBlock.java:262)
    at com.facebook.presto.spi.block.LazyBlock.getLoadedBlock(LazyBlock.java:253)
    at com.facebook.presto.spi.Page.getLoadedPage(Page.java:247)
    at com.facebook.presto.operator.TableScanOperator.getOutput(TableScanOperator.java:245)
    at com.facebook.presto.operator.Driver.processInternal(Driver.java:373)
    at com.facebook.presto.operator.Driver.lambda$processFor$8(Driver.java:282)
    at com.facebook.presto.operator.Driver.tryWithLock(Driver.java:672)
    at com.facebook.presto.operator.Driver.processFor(Driver.java:276)
    at com.facebook.presto.execution.SqlTaskExecution$DriverSplitRunner.processFor(SqlTaskExecution.java:973)
    at com.facebook.presto.execution.executor.PrioritizedSplitRunner.process(PrioritizedSplitRunner.java:162)
    at com.facebook.presto.execution.executor.TaskExecutor$TaskRunner.run(TaskExecutor.java:477)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

【问题讨论】:

当您将问题隔离到table1 时,您是否还能够简化重现问题的查询?您是否尝试查看 table1 格式和特定​​文件?文件架构和表架构之间是否存在任何不匹配?您能否将问题隔离到单个文件? @PiotrFindeisen 我在 presto 的调试模式下发现了一个异常。在上面添加了详细信息。不确定如何调查单个文件,因为 S3 中有大量 parquet 文件。我不明白为什么 Hive-sql 能够提供行。 试试set session hive.parquet.use-column-names = true @PiotrFindeisen 我在 presto cli 中执行语句时看到此错误。 Query 20180917_103930_00031_4988g failed: line 1:29: mismatched input '-'. Expecting: '.', '=' set session hive.parquet_use_column_names=true 工作。 【参考方案1】:

Presto 默认根据位置将 Parquet 中的字段与表模式匹配。如果您的字段顺序不同(例如,随着时间的推移写得不同),您需要启用按名称匹配。你可以通过hive.properties 做到这一点:

hive.parquet.use-column-names = true

或在会话级别:

设置会话 hive.parquet_use_column_names = true;

这是一个相关问题:https://github.com/prestodb/presto/issues/8911

【讨论】:

以上是关于EMR-Presto 和 Athena 的查询结果差异的主要内容,如果未能解决你的问题,请参考以下文章

如何将完整的 Athena 查询结果下载到 CSV 文件

Amazon athena 无法读取 S3 Access 日志文件,Athena 选择查询为每一列返回空结果集

在 Zeppelin 中保存 AWS Athena 查询的结果

查找雅典娜查询结果的来源

Athena Query - “NOT IN” 性能缓慢

AWS Athena 上的偏移量