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:
- DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMP
 - (EMPNO CHAR(6) NOT NULL,
 - FIRSTNME VARCHAR(12) NOT NULL,
 - MIDINIT CHAR(1) NOT NULL,
 - LASTNAME VARCHAR(15) NOT NULL,
 - WORKDEPT CHAR(3),
 - PHONENO CHAR(4)
 - )
 - ON COMMIT DROP TABLE or
 - ON COMMIT DELETE / PRESERVE ROWS
 - ;
 - CREATE INDEX SESSION.EMPX1 ON SESSION.TEMP_EMP
 - (LASTNAME ASC)
 - ;
 - INSERT INTO SESSION.TEMP_EMP
 - SELECT EMPNO,
 - FIRSTNME,
 - MIDINIT,
 - LASTNAME,
 - WORKDEPT,
 - PHONENO
 - FROM EMP
 - ;
 - SELECT *
 - FROM SESSION.TEMP_EMP
 - ;
 
                    
                
                
            
        
浙公网安备 33010602011771号