13. 考虑使用全局临时表

如果所处理的数据会一直保留在应用的逻辑工作单元中,可以考虑使用全局临时表(global temporary table,GTT),而不要反复建立或物化数据。如果在程序执行期间多次获取或物化同样的数据,可以把这些数据在一个GTT中加载一次,然后在代码的其他地方引用这个表。

例如,一个程序有多个游标,每个游标包含多个表联接。另外,每个游标都包含同样的表Table1,而这恰好是各个查询的驱动表。处理各个游标时,可能必须从数据库获取相同的行来完成Table1处理。这样一来,就会导致对相同数据额外的I/O处理。

所以,更好的做法是先获取Table1数据,把它插入到一个GTT中,然后在各个游标中引用这个GTT。这会消除对Table1的重复I/O。GTT也很适合创建一个概要数据表,可以在逻辑工作单元中的其他查询中引用。

警告:有两类GTT:一类是DBA创建的GTT,另一类是应用代码中声明的GTT。使用DBA创建的全局表时要特别当心,因为它们不能有索引。把这些表加入一个多表联接时,可能会导致性能问题。不过,如果在应用代码中声明一个全局表,在其中加载数据之前,应用代码可以在这个表上创建索引。如果是这样,会随着数据的插入收集动态统计信息,而且由于可以使用这个索引和统计信息,联接通常会更高效。另外,要记住由于应用代码中声明的全局表有更大的灵活性,所有引用这些全局表的SQL语句会作为动态SQL执行,而引用DBA创建的全局表的SQL则作为静态SQL执行。

下面的例子展示了代码中如何声明和创建一个全局临时表。在应用代码中声明全局临时表时,所有者必须使用SESSION:

 

  1. DECLARE GLOBAL TEMPORARY TABLE   SESSION.TEMP_EMP  
  2.  (EMPNO      CHAR(6)            NOT NULL,  
  3.   FIRSTNME   VARCHAR(12) NOT NULL,  
  4.   MIDINIT    CHAR(1)            NOT NULL,  
  5.   LASTNAME   VARCHAR(15) NOT NULL,  
  6.   WORKDEPT   CHAR(3),  
  7.   PHONENO    CHAR(4)  
  8.  )  
  9. ON COMMIT DROP TABLE     or  
  10. ON COMMIT DELETE / PRESERVE ROWS  
  11. ;  
  12.  
  13. CREATE INDEX SESSION.EMPX1 ON SESSION.TEMP_EMP  
  14.       (LASTNAME  ASC)  
  15. ;  
  16.  
  17. INSERT INTO SESSION.TEMP_EMP  
  18. SELECT EMPNO,  
  19.        FIRSTNME,  
  20.        MIDINIT,  
  21.        LASTNAME,  
  22.        WORKDEPT,  
  23.        PHONENO  
  24. FROM EMP  
  25. ;  
  26.  
  27. SELECT *  
  28. FROM SESSION.TEMP_EMP  
posted @ 2013-07-12 09:24  小土_  阅读(234)  评论(0编辑  收藏  举报