gpt4 book ai didi

java - 使用 Spring 数据源时 Apache Drill "limit 0"查询

转载 作者:行者123 更新时间:2023-11-30 06:25:08 25 4
gpt4 key购买 nike

TL;DR

我有一个 Spring Boot 应用程序,它使用存储在文件系统上的 parquet 文件。为了访问它们,我们使用 Apache Drill。

由于我有多个用户可能访问它们,因此我在 Spring 中设置了一个连接池。

当我使用连接池时,Drill 在执行实际查询之前会以某种方式执行“限制 0”查询,这会影响性能。当我通过从直接连接获得的简单语句运行查询时,不会执行相同的“限制 0”查询。

这似乎与Spring JdbcTemplate 使用PreparedStatements 而不是简单的Statement 有关。

有没有办法摆脱那些“limit 0”查询?

-- 详细信息 --

Spring配置类中的连接池如下所示:

@Bean
@ConfigurationProperties(prefix = "datasource.parquet")
@Qualifier("parquetDataSource")
public DataSource parquetDataSource() {
return DataSourceBuilder.create().build();
}

开发配置文件YML文件中对应的属性为:

datasource:
parquet:
url: jdbc:drill:drillbit=localhost:31010
jdbcUrl: jdbc:drill:drillbit=localhost:31010
jndiName: jdbc/app_parquet
driverClassName: org.apache.drill.jdbc.Driver
maximumPoolSize: 5
initialSize: 1
maxIdle: 10
maxActive: 20
validation-query: SELECT 1 FROM sys.version
test-on-borrow: true

当我使用使用上述 Drill DataSource 创建的 JdbcTemplate 执行查询时,可能会执行 3 个不同的查询:

  1. 验证查询 SELECT 1 FROM sys.version ;
  2. “限制 0”查询,类似于 SELECT * FROM (<my actual query>) LIMIT 0 ;
  3. 我的实际查询。

下面是执行代码(parquetJdbcTemplate 是扩展 org.springframework.jdbc.core.JdbcTemplate 的类的实例):

parquetJdbcTemplate.query(sqlQuery, namedParameters,
resultSet -> {
MyResultSet result = new MyResultSet();
while (resultSet.next()) {
// populate the "result" object
}
return result;
});

这是我的 Drill 监视器的“个人资料”页面的屏幕截图: monitor screenshot

底部查询是“限制 0”查询,然后在中间有验证查询,在顶部(即使未显示查询)是返回我想要的数据的实际查询。

如您所见,“limit 0”查询的运行时间超过了整个执行时间的 1/3。验证查询很好,因为执行时间可以忽略不计,并且需要检查连接。

事实是,当我通过 Drill 驱动程序使用 Connection 执行相同的查询时(因此,没有池),我只能在 UI 监视器中看到我的实际查询:

public void executeQuery(String myQuery) {
Class.forName("org.apache.drill.jdbc.Driver");
Driver.load();
Connection connection = DriverManager.getConnection("jdbc:drill:drillbit=localhost:31010");
Statement st = connection.createStatement();
ResultSet resultSet = st.executeQuery(myQuery);
while (resultSet.next()) {
// do stuff
}
}

monitor screenshot正如您所看到的,总执行时间提高了很多(约 14 秒而不是约 26 秒),只是因为没有执行“limit 0”查询。

据我所知,执行这些“limit 0”查询是为了验证并获取有关 Parquet 文件的底层架构的信息。有没有办法在使用连接池时禁用它们?理想情况下,我仍然希望使用PreparedStatements而不是简单的语句,但如果需要,我可以切换到简单的语句,因为我可以完全控制这些查询(因此,除非有人破解了已部署的工件,否则不可能进行SQL注入(inject))。

最佳答案

你是对的,Drill 执行 limit 0 个事先准备好的语句来获取有关模式的信息。我认为没有办法禁止这种行为。虽然我建议启用默认情况下为 false 的 planner.enable_limit0_optimization 选项,但这可能会限制 0 查询执行速度。速度限制 0 查询的另一种方法是通过 View 使用或直接在查询中使用强制转换显式指示架构。

关于不显示查询,我认为这已在最新的 Drill 版本中修复。

关于java - 使用 Spring 数据源时 Apache Drill "limit 0"查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47329015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com