我已成功使用Oracle的JDBC客户端(来自oracle的最新ojdbc7.jar)设置Apache Drill(最新版本1.9)作为存储插件:
{
"type": "jdbc",
"driver": "oracle.jdbc.driver.OracleDriver",
"url": "jdbc:oracle:thin:@server:1521/myservicename",
"username": "TEST_USER",
"password": "password",
"enabled": true
}
我可以进行查询,但即使是最简单的事情也需要几分钟才能执行。 查询单行表需要78秒。 只需设置默认架构需要一分钟:
0: jdbc:drill:zk=local> use oracle.TEST_USER
. . . . . . . . . . . > ;
+-------+-------------------------------------------------+
| ok | summary |
+-------+-------------------------------------------------+
| true | Default schema changed to [oracle.TEST_USER] |
+-------+-------------------------------------------------+
1 row selected (77,5 seconds)
但是我已经使用一个简单的hello-world风格的java应用程序进行了测试,使用相同连接字符串的连接可以正常工作,完整的表提取时间约为0.1秒。
jdbc:oracle:thin:@server:1521/myservicename
我已经从Ubuntu和Mac进行了测试,并尝试设置java的随机源,因为其他答案指出是潜在的性能问题:
export DRILL_JAVA_OPTS="$DRILL_JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
这里发生了什么?这是一个已知问题还是有一些解决方法?
我使用了钻孔嵌入式。
答案 0 :(得分:1)
我能够找到这个问题的根本原因。
问题不是慢查询,而是Drill的元数据查询中的非最佳预取策略。 就我而言,数据库非常庞大,并且每百个表都有数千个模式(oracle用户)。 oracles默认fetchsize为10,导致数百个DB往返。
每个Apache Drill JDBC查询都在检查元数据。
在Apache Drill: JdbcStoragePlugin.java#L351内:
java.sql.DatabaseMetaData.getSchemas()
在Apache Calcite (Drill dependency): JdbcMeta.java#L323内:
java.sql.DatabaseMetaData.getTables(...)
这两个部分都不会覆盖任何默认的fetchsize,并且通过wireshark,我可以逐字逐句地看到每个只有10行的包。 (数据库服务器的延迟非常高,位于其他地方)
我已经通过手动调用setFetchSize重新编译了Apache Drill,这大大缩短了响应时间。到目前为止,我没有对Calcite进行修补,但也可能会这样做。
总的来说,我认为在获取元数据时,应该考虑编写高性能JDBC代码的常规步骤,因为真实世界的场景很容易最终得到更大的元数据(例如,超过10个表或模式) 另一个想法是缓存,但我还没有在Drill的JDBC存储插件中看到任何元数据缓存。
答案 1 :(得分:1)
对于那些有同样问题并试图找到答案的人。
我更新了 oracle jar 文件
/oracle/jdbc/defaultConnectionProperties.properties
并添加
oracle.jdbc.defaultRowPrefetch=200
我使用 7zip 打开和编辑文件内容
注意:您需要为您的案例找到最佳的 rowPrefetch
我阅读How to fix "<string> DeprecationWarning: invalid escape sequence" in Python?是为了给我一个想法。