查询优化:DBMS_METADATA.GET_DDL(Oracle)

3
我想获取我所有表的所有表定义。而且我想要快速完成(它是我正在运行的脚本的一部分)。
我正在使用Oracle 11g,并且我有700个表。在普通的JDBC代码中,它需要4分钟并执行以下操作:
s = con.statement("select DBMS_METADATA.GET_DDL(object_type,object_name) from user_objects where object_type = 'TABLE');
s.execute();
rs = s.getResultSet();
while(rs.next()){
 rs.getString(1);
}

所以我想优化这段代码,并达到大约20秒的速度。

我已经通过创建14个线程,每个线程打开一个连接到数据库并读取部分信息,使用rownum上的mod来达到了40-50秒的时间。

但这还不够。

我正在考虑以下方向:

  1. http://docs.oracle.com/cd/B10501_01/java.920/a96654/connpoca.htm#1063660 - 连接缓存。是否可以通过使用connectionCaching来替换我的14个连接来加快速度?

  2. 是否可能将此函数访问的表保留在KEEP缓存区域中?

  3. 是否有任何方法索引这里的一些信息?

  4. 任何其他建议都将不胜感激。

谢谢


这听起来像是你只有在不使用版本控制时才会问的问题。如果是这种情况,真正的答案是:使用版本控制。 - Jon Heller
3个回答

5

即使表没有更改,是否必须始终获取DDL?否则,仅获取上次检索时ALL_OBJECTS.LAST_DDL_TIME已更改的那些表的DDL。

另一个选项是编写自己的GET_DDL,并以一种能够同时获取多个表的方式进行。


1

很抱歉,没有简单的方法可以使其更快。整个GET_DDL功能是用Java实现的,并使用XSLT转换作为生成过程的一部分。

也许你会发现这个更快。 http://metacpan.org/pod/DDL::Oracle


3
在建议使用第三方工具完成此任务时,我会非常谨慎,特别是那些似乎已经有几年没有更新的工具(这意味着它肯定不会支持新功能,比如使用序列设置列默认值)。 - Frank Schmitt
3
是的,你说得对。另一方面,DBMS_METADATA也有(或曾经有)它的陷阱,并且在XE版本中不起作用。它无法在任何其他缺少JVM的数据库安装上运行。我经常使用的另一种方法是:EXP FULL=YES ROWS=NO,然后是IMP SHOW=YES。然后,我通过手工编写的Perl脚本处理imp的输出。 - ibre5041

1

我首先会采用HAL的建议,只捕获更改,但我也会考虑消除我不需要的任何选项--例如STORAGE子句。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接