【问题标题】:Presto JDBC Large Query Extremely SlowPresto JDBC 大查询极慢
【发布时间】:2020-04-26 14:28:13
【问题描述】:

问题

  1. 使用 JDBC 驱动程序从 Presto 查询中迭代一个大的 ResultSet 非常耗时。每个批处理调用似乎几乎都需要 60 秒,这很可疑(可能是由于某些超时引起的?)。
  2. 出于某种原因,初始 executeQuery 方法几乎需要 45 秒,这很可疑。

查询

我正在使用 Java JDBC Presto 驱动程序对 Presto 执行一个简单的查询,看起来基本上像:

SELECT stringA, stringB 
FROM {table} 
LIMIT 500000

stringAstringB 很小 - 每个大约 10 个字符。
使用 teradata 驱动程序在 DbVisualizer 中运行时,我的查询在 10 秒内完成。
但是,当我使用 0.230 presto-jdbc 驱动程序从 Spring Java 应用程序运行相同的查询时,它似乎会分批(大约 75,000 个)返回结果,并且每批需要一分钟以上才能返回。

我已经阅读了一些有关 Presto 的 targetResultSize 查询参数的信息,但我无法使用 JDBC 驱动程序/连接来设置它。我读过默认情况下 presto 一次只会返回 1MB 的数据?不确定这是否是我上述问题 #1 的原因 - 弄清楚如何配置它会很棒。

Java 代码

public List<Object> getResultSetUsingDriverManager(ChronoLocalDate chronoLocalDate) throws SQLException {
    long start = System.currentTimeMillis();

    Properties properties = new Properties();
    properties.setProperty("user", USERNAME);
    properties.setProperty("password", PASSWORD);
    properties.setProperty("SSL", "true");

    final Connection connection = DriverManager.getConnection(URL, properties);

    log.warn("Presto connection acquired in " + (System.currentTimeMillis() - start) + "ms");

    Statement statement = connection.createStatement();

    ResultSet resultSet = statement.executeQuery(query);

    log.warn("Presto query executed in " + (System.currentTimeMillis() - start) + "ms");

    List<Object> collection = new ArrayList<>();

    int counter = 0;
    long batchStart = System.currentTimeMillis();
    while (resultSet.next()) {
        counter++;
        if (counter % 1000 == 0) {
            log.warn("current count {} and took {}ms", counter, (System.currentTimeMillis() - batchStart));
            batchStart = System.currentTimeMillis();
        }
    }
    log.warn("Results extracted in " + (System.currentTimeMillis() - start));

    return collection;
}

输出

2020-01-08 17:34:31.704  WARN 29368 --- ...       : Presto connection acquired in 0ms
2020-01-08 17:35:16.705  WARN 29368 --- ...       : Presto query executed in 45003ms
2020-01-08 17:37:18.242  WARN 29368 --- ...       : current count 1000 and took 121537ms
2020-01-08 17:37:18.244  WARN 29368 --- ...       : current count 2000 and took 2ms
2020-01-08 17:37:18.245  WARN 29368 --- ...       : current count 3000 and took 1ms
...
2020-01-08 17:37:18.294  WARN 29368 --- ...       : current count 75000 and took 1ms
2020-01-08 17:38:18.857  WARN 29368 --- ...       : current count 76000 and took 60563ms
2020-01-08 17:38:18.858  WARN 29368 --- ...       : current count 77000 and took 1ms
...
2020-01-08 17:38:18.941  WARN 29368 --- ...       : current count 151000 and took 0ms
2020-01-08 17:39:19.241  WARN 29368 --- ...       : current count 152000 and took 60300ms
2020-01-08 17:39:19.242  WARN 29368 --- ...       : current count 153000 and took 1ms
...
2020-01-08 17:39:19.311  WARN 29368 --- ...       : current count 250000 and took 0ms
2020-01-08 17:39:19.311  WARN 29368 --- ...       : Results extracted in 287609

版本信息

  • Java 11
  • com.facebook.presto presto-jdbc 0.230
  • Spring Boot 2.1.6.RELEASE
  • Presto 版本:302-e.3(星爆版)

【问题讨论】:

  • 您的比较不公平,因为您的代码包括从查询结果创建的对象,当显示原始结果时,这并没有发生。 MySpecialObject.RESULT_SET_EXTRACTOR.extractData 到底在做什么?最后,您不应该使用 String concat/replace 来修改您的查询。而是使用PreparedStatement 来设置所需的查询参数。
  • 我们对 Java 11 进行了某些修复,这些修复可能会影响您的情况。您可以使用 Presto 327(服务器和 JDBC)重复您的实验吗? prestosql.io/download.html
  • @M.Deinum 提取器正在做一些非常轻量级的事情。完全删除它对行为没有影响。我同意我不应该在查询中使用 String concat ,但这也不是问题的一部分。我已经简化了示例中的代码,以专注于我面临的核心问题。
  • @PiotrFindeisen 感谢您的提醒。不幸的是,我个人无法控制我正在连接的 Presto 服务器,但我可以更新 JDBC 驱动程序。我会看看我能做些什么并报告我的发现。

标签: java spring presto presto-jdbc starburst


【解决方案1】:

最近几个月,我们修复了与 Java 11 上的客户端连接相关的问题。

请将您的 JDBC 驱动升级到 327。

或者在客户端降级到 Java 8。

【讨论】:

  • 我最终设置了一个仅包含与 presto 的连接的快速测试应用程序。我运行了与 Java 8 和 Java 11 运行上述查询完全相同的代码。当使用 Java 8 运行时,查询立即完成,但使用 Java 11 我看到了上面提到的同样缓慢的性能。简单地更新 JDBC 驱动程序并没有提高性能 - 降级到 Java 8 是我找到的唯一解决方案。
  • 感谢您分享您的结果。这是非常令人担忧的。您是否有权通过 Java 8 和 11 对 Presto 服务器 327 和 JDBC 327 重复测试? (即使在与之前测试完全不同的环境中也很有趣)
  • 我目前无法升级 Presto 服务器 - 我真的只能控制驱动程序/客户端。但我正在努力查看是否可以升级服务器。如果我们确定302-e.3 与 Java 11 JDBC 客户端完全不兼容,那将使得版本升级选项变得更加必要。也感谢 Piotr 的反应如此迅速,非常感谢。
  • 302 版本已经很老了,所以你很容易找到其他升级的理由。我们可以在 Presto 社区闲暇prestosql.io/slack.html 上进行更多讨论。那里见!
猜你喜欢
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
相关资源
最近更新 更多