小议星型转换

星型转换是一个非常强大的优化技术,它是通过对原来的SQL语句的隐式的改写来实现的。终端用户并不需要知道有关星型转换的任何细节。数据库优化器会在合适的时候进行星型转换。
要获得星型转换的最大性能,需要遵循以下基本的指导:
  1. 在事实表的每个外键列上都应该创建bitmap索引。
  2. 需要将初始化参数STAR_TRANSFORMATION_ENABLED设置为true,这可以获得star query的重要的优化特性。缺省为false,是为了向下兼容。
如果数据仓库能够满足这个要求,则查询会使用star transformation,而这是提高基于事实表的查询效率的主要的技术。

数据库进行星型查询时,会使用两个基本的阶段:
  1. 第一个阶段从事实表(或者说结果集)里获取所有必要的记录行。由于这是通过bitmap索引来检索数据,因此比较高效。
  2. 第二个阶段将该结果集与维度表进行关联。这叫做semi-join(也就是exists和in写法)。
注意:只有oracle企业版才有bitmap索引。标准版不支持bitmap索引和星型转换。

SQL> connect sh/sh
SQL> set autotrace traceonly exp;
SQL> SELECT ch.channel_class, c.cust_city,
  2         t.calendar_quarter_desc,
  3         SUM(s.amount_sold) sales_amount
  4  FROM sales s,times t,customers c,channels ch
  5  WHERE s.time_id = t.time_id AND
  6        s.cust_id = c.cust_id AND
  7        s.channel_id = ch.channel_id AND
  8        c.cust_state_province = 'CA' AND
  9   ch.channel_desc IN ('Internet','Catalog') AND
 10   t.calendar_quarter_desc IN ('1999-Q1','1999-Q2')
 11  GROUP BY ch.channel_class, c.cust_city, t.calendar_quarter_desc;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=ALL_ROWS (Cost=786 Card=1 Bytes=73)
   1    0   TEMP TABLE TRANSFORMATION
   2    1     LOAD AS SELECT OF 'SYS_TEMP_0FD9D6602_F1E23'
   3    2       TABLE ACCESS (FULL) OF 'CUSTOMERS' (TABLE) (Cost=332 Card=383 Bytes=9958)
   4    1     HASH (GROUP BY) (Cost=455 Card=1 Bytes=73)
   5    4       HASH JOIN (Cost=454 Card=1 Bytes=73)
   6    5         HASH JOIN (Cost=450 Card=2 Bytes=104)
   7    6           HASH JOIN (Cost=448 Card=32 Bytes=1184)
   8    7             TABLE ACCESS (FULL) OF 'TIMES' (TABLE) (Cost=15 Card=183 Bytes=2928)
   9    7             PARTITION RANGE (SUBQUERY) (Cost=432 Card=254 Bytes=5334)
  10    9               TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'SALES' (TABLE) (Cost=432 Card=254 Bytes=5334)
  11   10                 BITMAP CONVERSION (TO ROWIDS)
  12   11                   BITMAP AND
  13   12                     BITMAP MERGE
  14   13                       BITMAP KEY ITERATION
  15   14                         BUFFER (SORT)
  16   15                           TABLE ACCESS (FULL) OF 'CHANNELS' (TABLE) (Cost=3 Card=2 Bytes=42)
  17   14                         BITMAP INDEX (RANGE SCAN) OF 'SALES_CHANNEL_BIX' (INDEX (BITMAP))
  18   12                     BITMAP MERGE
  19   18                       BITMAP KEY ITERATION
  20   19                         BUFFER (SORT)
  21   20                           TABLE ACCESS (FULL) OF 'TIMES' (TABLE) (Cost=15 Card=183 Bytes=2928)
  22   19                         BITMAP INDEX (RANGE SCAN) OF 'SALES_TIME_BIX' (INDEX (BITMAP))
  23   12                     BITMAP MERGE
  24   23                       BITMAP KEY ITERATION
  25   24                         BUFFER (SORT)
  26   25                           TABLE ACCESS (FULL) OF 'SYS_TEMP_0FD9D6602_F1E23' (TABLE (TEMP)) (Cost=2 Card=1 Bytes=13)
  27   24                         BITMAP INDEX (RANGE SCAN) OF 'SALES_CUST_BIX' (INDEX (BITMAP))
  28    6           TABLE ACCESS (FULL) OF 'SYS_TEMP_0FD9D6602_F1E23'(TABLE (TEMP)) (Cost=2 Card=383 Bytes=5745)
  29    5         TABLE ACCESS (FULL) OF 'CHANNELS' (TABLE) (Cost=3 Card=2 Bytes=42)

这就是一个星型转换的例子。对于这个例子来说,数据库会进行两个阶段:
第一个阶段,数据库使用sales表的外键列的bitmap索引来从sales表里标识并检索出所有必须的数据行,得到一个结果集。会使用如下的SQL来进行改写:
SELECT s.amount_sold
FROM sales s
WHERE time_id IN (SELECT time_id
                  FROM times
                  WHERE calendar_quarter_desc IN('1999-Q1','1999-Q2'))
AND   cust_id IN (SELECT cust_id
                  FROM customers
                  WHERE cust_state_province = 'CA')
AND channel_id IN(SELECT channel_id
                  FROM channels
                  WHERE channel_desc IN ('Internet','Catalog'));
这是算法中的转换步骤,因为原来的星型查询已经转换为这样一个子查询的表现形式。在这个星型查询中,先扫描times表,获得符合1999-Q1和1999-Q2的time_id。然后根据这些time_id,再使用sales表上的time_id上的bitmap索引来找到事实表里对应到1999-Q1的数据行集。这个数据行集以bitmap里的bit位来表现,也就是1和0的组合,这些1和0就对应到事实表里符合该条件的、在该数据行集里的rowid。执行计划里的BITMAP KEY ITERATION步骤就体现了这个过程。然后使用类似的方法获得事实表里对应到1999-Q2的数据行集。然后采用OR操作符,将Q1的结果集与Q2的结果集进行合并,也就是BITMAP MERGE步骤。

对于customer维度和product维度,也会采用类似的额外的方法获得数据行集。

在该查询汇总,我们得到三个以bitmap所展现的数据行集。

每个bitmap对应到一个单独的维度表,每个bitmap表现了事实表里符合单个维度的限制。这三个bitmap通过使用bitmap AND操作组合成一个bitmap。
最终的bitmap就表现了事实表里符合所有条件的行集。这也就是最终的rowid结果集,然后通过该bitmap得到最终的结果。注意,在这个过程中,并没有实际访问过事实表,所有这些操作都是在维度表和bitmap索引上实现的。由于bitmap索引对数据进行了压缩,因此基于结果集的操作特别高效。

该查询的第二个阶段,就是将事实表所返回的数据行与维度表关联。在与维度表关联时,也就是在扫描维度表的时候,CBO会自动判断,如果维度表很小,则全表扫描,如果维度表很大,CBO可能会创建临时表,用来包含这两个阶段所要用到的记录。比如这里再扫描customers维度表时,就把customers表里的记录取出,并放到了一个临时表里。在关联维度时,通常会采用hash join的方式。

这基本就是星型转换的过程。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9842/viewspace-346823/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9842/viewspace-346823/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值