首页 文章

在Oracle中获取多个blob

提问于
浏览
1

我们将数据以序列化形式存储在Oracle表中 . 保存序列化数据的列是BLOB类型 . 我们有一个存储过程来查询表并将结果作为sys_refcursor返回 . 存储过程接受逗号分隔形式的键列表,其中将获取blob .

环境 - JRE 1.6 Oracle 11g

问题:当应用程序请求数据为8行或10行时,我们希望存储过程在单个数据库往返中返回带有二进制数据的所有结果行 . 这可能吗?或者用最少的数据库往返来获取结果的最佳方法是什么 .

(我们已经将fetchRowsize设置为10,因此可以获取多行 . 我们还将setLOBPrefetchSize设置为足够大的值(3 Meg) . 但是这些似乎没有什么区别.resultSet.getBytes()具有重要意义指示根据请求获取数据的时间)

我错过了什么?我们是否有任何跟踪来启用/检查下面发生了什么?

2 回答

  • 0

    BLOB故意触发一些特定的行为,因为它们可能非常大(取决于块大小,但最大大小至少为8 TB) . 驱动程序并不总是事先知道将传输多少数据,因此驱动程序默认采用安全路径 .

    我知道你只想在一次往返中想要它,可能是因为你的网络延迟?如果没有,请说明 .

    我们开发的标准软件包遇到了同样的问题,客户端在连接设备上检索到全球范围内的大量数据 . 我们解决了它如下:

    • 最初,我们使用了一个存储过程,该过程采用带有最后检索数据行的哈希值的参数 . 存储过程检查当前数据行的哈希值 . 如果没有不同,它只返回一个 Headers . 如果不同,它将所有内容放在一个大块中并将其发回 . 通过这种方式,它避免了在全球范围内传输大量信息,因为高网络延迟通常伴随着低带宽 . 此外,往返次数减少了 .

    • 过去两年我们在公司之间插入了一个不同的产品(网络服务提供商) . 它自己进行压缩和重复数据删除,并进一步减少带宽需求 . 此外,它仅在Web服务和Oracle RDBMS之间使用SQL * Net . webservice使用bson(二进制格式的json)进行通信 .

    由于劳动力成本低,我建议只从存储过程中返回一个LOB,其中包含所有内容 . 甚至可能压缩它或使用客户端的缓存 .

    上述选项2需要引入更多的劳动力 .

  • 0

    如果您碰巧使用Oracle的瘦JDBC驱动程序,您可能想尝试将连接属性 useFetchSizeWithLongColumn 设置为true,请参阅http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/index.html?oracle/jdbc/OracleDriver.html . 但是,由于属性名称表示它适用于LONG列,并且它可能对BLOB列没有任何影响 . (不幸的是,我无法在这里自己尝试 . 但是,http://ora-jdbc-source.googlecode.com/svn/trunk/OracleJDBC/src/oracle/jdbc/driver/OracleResultSetImpl.java下的源代码似乎没有使用useFetchSizeWithLongColumn来区分LONG / LOB,只是"re-opens streams" . )

    有关验证/跟踪,请参阅以下示例代码:http://steveracanovic.blogspot.de/2009/08/using-usefetchsizewithlongcolumn-and.html

    如果连接属性不适用于BLOB,则可以尝试返回LONG . 但是,似乎没有一种很好的从BLOB转换为LONG的方法 . 以下讨论(参见答案)提到了在PL / SQL中使用RAW变量的方法:http://oracle.mscer.com/q_oracle_41102.html . 正如您在使用存储过程中提到的那样,您可能想尝试这样做 .

    (请注意,设置连接属性意味着预取的LONG数据可能会占用大量内存 . )

    (再次,对不起,我不能自己尝试这种方法,因为我没有Oracle DB,所以无法提供详细信息 . 但是在过去两个小时内没有人想出答案......)

相关问题