使用实例化的查询表加速 DB2 UDB EEE 中的查询
|
|
级别: 初级
Alexander Kuznetsov
, 芝加哥,伊利诺斯州
2002 年 8 月 01 日
有时候,物理数据库结构中的一次简单更改会引人注目地改进查询性能。除了索引外,DB2 UDB 还为您提供了总结表(实例化的查询表),在许多情况下,这些表比索引更有效。本文将提供一些示例来演示使用总结表的优点。
简介
有时候,物理数据库结构中的一次简单更改会显著地改进查询性能。除了索引外,DB2® Universal Database™ 还为您提供实例化的查询表(在版本 7.2 和更早的发行版中,称为“总结表”),在许多情况下,这些表比索引更有效。其实,实例化的查询表(materialized query table,MQT)是根据查询结果定义的表。本文将描述一些示例,在这些示例中,与单独使用索引相比,MQT 提供更有效的性能改进。
优点:避免重复计算
MQT 可以帮助您避免对于每次查询重复计算(如 SUM)。让我们假设有一个名为 CUSTOMER_ORDER 的表,它存储了好几年的客户订单。该表的记录超过一百万条,平均行宽为 400 个字节。现在,假设我们必须对 2001 年的订单运行多次查询,并且我们只需要表中的三列,如下所示:
select SUM(AMOUNT), trans_dt
from db2inst2.CUSTOMER_ORDER
where trans_dt between '1/1/2001' and '12/31/2001'
group by trans_dt
|
或
select SUM(AMOUNT), status
from db2inst2.CUSTOMER_ORDER
where trans_dt between '1/1/2001' and '12/31/2001'
group by status
|
如果有适当的索引,那么这些查询被作为索引扫描来执行。 清单 1是执行计划的摘录,它表明使用索引扫描运行查询的预计成本是 152455。
清单 1. 对 CUSTOMER_ORDER 表运行查询的成本
-------------------- SECTION ---------------------------------------
Section = 1
SQL Statement:
select SUM(AMOUNT), trans_dt
from db2inst2.CUSTOMER_ORDER
where trans_dt between '1/1/2001' and '12/31/2001'
group by trans_dt
Estimated Cost = 152455
Estimated Cardinality = 378
(这里省略了一些行)
Subsection #2:
Access Table Name = DB2INST2.CUSTOMER_ORDER ID = 2,591
| #Columns = 1
| Index Scan: Name = DB2INST2.CUST_ORD_TRANS_DT ID = 4
| | Index Columns:
| | | 1: TRANS_DT (Ascending)
(这里省略了一些行)
End of section
|
现在,让我们创建一个 MQT,它包含我们所需的列和行,包括总和计算。
CREATE TABLE DB2INST2.SUMMARY_CUSTOMER_ORDER_2001 AS
(SELECT SUM(AMOUNT) AS TOTAL_SUM,
TRANS_DT,
STATUS
FROM DB2INST2.CUSTOMER_ORDER
WHERE TRANS_DT BETWEEN '1/1/2001' AND '12/31/2001'
GROUP BY TRANS_DT,
STATUS)
DATA INITIALLY DEFERRED REFRESH DEFERRED;
|
子句 DATA INITIALLY DEFERRED 表示:数据不作为 CREATE TABLE 语句的一部分插入到表中。而是您必须执行 REFRESH TABLE 语句来填充表。子句 REFRESH DEFERRED 表示:表中的数据仅作为发出 REFRESH TABLE 语句时的快照反映查询结果。有关创建 MQT 的更多信息,请参阅 SQL Reference。
当我们准备填充刚才创建的 MQT 时,发出下面的语句: