海鸥航际

JAVA站
posts - 11, comments - 53, trackbacks - 1, articles - 102

让你的连接查询加速

Posted on 2005-02-03 21:00 海天一鸥 阅读(170) 评论(0)  编辑  收藏 所属分类: Java数据库技术

Oracle9i引入了一种新的方法来加速对大型数据仓表格的连接(join)查询。这种新的方法,即位图连接索引(bitmap join index),要求创建一个索引,有这个索引在它被创建的时候进行合并操作,然后为连接中用到的关键字创建一个位图索引。

<a href="http://ad.cn.doubleclick.net/click%3Bh=v3|3214|3|0|%2a|r%3B13561728%3B0-0%3B0%3B10768906%3B31-1|1%3B8724972|8742868|1%3B%3B%7Esscs%3D%3fhttp%3a%2f%2fhttp://ad.doubleclick.net/clk;13464484;4278154;m?http://www.mymai.com/index1.aspx?s=zdmail" target="_blank"><IMG SRC="http://m2.cn.doubleclick.net/1012548/mpu_mymai.swf " WIDTH=468 HEIGHT=60 BORDER=0 ></a>

位图连接索引背后的技术其实是把低基数数据列预先连接在一起,这样就让整体的连接(操作)进行得更快。在本文的例子里,我们将使用一个零件和供应商之间的多对多关系。每个零件都由多个供应商供应,而每个供应商能够提供多种零件。这个数据库里有200种不同类型的零件,供应商可以在(美国)所有50个州供应零件。

要创建一个位图连接索引,我们要使用下面的SQL。要注意CREATE INDEX句法里的FROM和WHERE子句。

create bitmap index
   part_suppliers_state
on
   inventory( parts.part_type, supplier.state)
from
   inventory i,
   parts     p,
   supplier  s
where
   i.part_id = p.part_id
and
   i.supplier_id = p.part_id;

尽管b-tree索引被用在标准的交叉记录(junction record)里,但是我们能够提高Oracle9i查询的性能,在这些查询里判断述词(predicate)会用到低基数数据列。例如,看看下面的查询,我们可以通过这个查询来获得北卡罗来纳的所有火花塞供应商:

select
   supplier_name
from
   parts
natural join
   inventory
natural join
   suppliers
where
   part_type = 'piston'
and
   state = 'nc'
;

在Oracle9i之前的版本里,这个查询会需要一个对所有三个表格进行嵌套循环连接(nested loop join)或者散列连接(hash join)。而在Oracle9i里,我们可以根据低基数数据列将这三个表格预先连接。

Oracle宣称,当所有的查询数据都驻留在索引之内的时候,使用这种索引方法能够把表格连接的速度提高7倍以上。然而在很多情况下,传统的散列连接或者嵌套循环连接可能会比位图连接做得更好。

位图连接不是一副万能药。下面就是索引的一些局限性:

  1. 被索引的数据列必须是低基数的——通常要少于300个完全不同的值。
  2. 在WHERE子句里,查询绝对不能索引哪些没有包含在索引里的数据列。
  3. 更新位图连接索引所需要的代价是相当高的。从实用的角度讲,位图连接索引被抛弃,而在每天晚上进行每日批量加载任务的时候才被重建。只有对于那些在处理的时候保持只读的Oracle数据仓,位图连接索引才会起作用。

总而言之,位图连接索引会极大地提高特定数据仓查询的速度,但是其代价是在为图索引创建的时候,需要预先连接表格。


只有注册用户登录后才能发表评论。


网站导航: