方法 1:在事实表与三个维度表之间定义适当的参照完整性约束
在 DB2 中,可以定义主键和外键约束,以允许数据库管理器对数据实施参照完整性约束。外键等参照约束还有助于提高性能。例如,如果修改 清单 2 中的查询中的子表达式 TMP1,去掉 PRODUCT_DIM 表上的本地谓词,那么,如果在 SALES_FACT.PRODUCT_ID 上创建一个外键约束,则优化器会消除 SALES_FACT 和 PRODUCT_DIM 之间的连接。如果创建了外键约束,则那样的连接被认为是无损的(lossless),可以从查询中移除,因为查询需要从 PRODUCT_DIM 中读取的数据在 SALES_FACT 表中都有,在 PRODUCT_DIM 与 SALES_FACT 的连接中,只引用到 PRODUCT_DIM 的主键,而没有引用 PRODUCT_DIM 的其它列。
在 星型模式布局 小节中描述的星型模式中,维度中存在的每个 DATE_ID、PRODUCT_ID 和 STORE_ID 在事实表中也必须存在。每个 ID 在维度表中都是惟一的,由为每个维度表创建的主键约束标识。因此,事实表保存产品被售出时的历史数据(定量)。下面的表描述了在这种模式中应该创建的主键和外键。维度中的每个惟一性 ID 在事实表中都有一个相应的外键约束。
表 | 列 | PK/FK | 目标表(列) |
DATE_DIM | DATE_ID | PK | 无 |
PRODUCT_DIM | PRODUCT_ID | PK | 无 |
STORE_DIM | STORE_ID | PK | 无 |
SALES_FACT | DATE_ID | FK | DATE_DIM (DATE_ID) |
SALES_FACT | PRODUCT_ID | FK | PRODUCT_DIM (PRODUCT_ID) |
SALES_FACT | STORE_ID | FK | STORE_DIM (STORE_ID) |
步骤 1A:对事实表执行 ALTER 操作,创建它与维度表之间的适当的 FK 关系。通过上面的表查看事实表与维度表之间的关系。再创建 SALES_FACT 列(DATE_ID,STORE_ID)上的一个索引,以便与 方法 3 中描述的 MDC 方法进行比较,方法 3 使用 (DATE_ID,STORE_ID) 上的一个块索引。
清单 23. 在 SALES_FACT 表中创建外键约束和索引 db2 -tvf alter_sales_fact.txt -z alter_sales_fact.log
清单 24.alter_sales_fact.txt 文件的内容 CONNECT TO DSS_DB;
ALTER TABLE SKAPOOR.SALES_FACT ADD CONSTRAINT DATE_DIM_FK FOREIGN KEY
(DATE_ID) REFERENCES DATE_DIM;
ALTER TABLE SKAPOOR.SALES_FACT ADD CONSTRAINT STORE_DIM_FK FOREIGN KEY
(STORE_ID) REFERENCES STORE_DIM;
ALTER TABLE SKAPOOR.SALES_FACT ADD CONSTRAINT PRODUCT_DIM_FK FOREIGN KEY
(PRODUCT_ID) REFERENCES PRODUCT_DIM;
CREATE INDEX SKAPOOR.IND_DATE_STORE ON SKAPOOR.SALES_FACT (DATE_ID, STORE_ID);
CONNECT RESET;
步骤 1B:收集关于所有表的统计信息:
优化器根据统计信息适当地计算备选查询执行计划(QEP)的成本,并选择最佳计划。在继续下一步骤之前,我们需要收集一些统计信息。
清单 25. 收集关于所有表的统计信息 db2 -tvf runstats.ddl -z runstats.log
清单 26. runstats.ddl 的内容 CONNECT TO DSS_DB;
RUNSTATS ON TABLE SKAPOOR.DATE_DIM WITH DISTRIBUTION AND INDEXES ALL;
RUNSTATS ON TABLE SKAPOOR.STORE_DIM WITH DISTRIBUTION AND INDEXES ALL;
RUNSTATS ON TABLE SKAPOOR.PRODUCT_DIM WITH DISTRIBUTION AND INDEXES ALL;
RUNSTATS ON TABLE SKAPOOR.SALES_FACT WITH DISTRIBUTION AND INDEXES ALL;
CONNECT RESET;