表的连接和其他高级调整技术

上传人:san****019 文档编号:21171819 上传时间:2021-04-25 格式:PPT 页数:60 大小:390.50KB
返回 下载 相关 举报
表的连接和其他高级调整技术_第1页
第1页 / 共60页
表的连接和其他高级调整技术_第2页
第2页 / 共60页
表的连接和其他高级调整技术_第3页
第3页 / 共60页
点击查看更多>>
资源描述
1、Oracle的连接非常复杂2、驱动表或者查询中第一张访问的表是获得更佳性能的关键3、如果优化器指定了错误的表作为查询中的驱动表,那么造成的差异将会天壤之别4、通常,基于成本的优化器会选择正确的表,但是表中的索引将影响它的正常工作。5、我们可以使用提示来改变表的连接顺序,但是如果需要调整多张表,那么会非常的麻烦6、如果我们需要使用提示来改变表的连接顺序,那么说明我们的索引出现了问题 连接方法嵌套连接(Nested loops join)排序合并连接(Sort-Merge join)集群连接(Cluster join)笛卡尔连接(Cartesian join)散列连接(Hash join)索引连接(Index join) 嵌套循环连接在嵌套循环连接中,Oracle从第一个行源中读取第一行,然后和第二个行源中数据进行对比。所有匹配的记录放在结果集中,然后oracle将读取第一个行源中的下一行。按这种方式直至第一个数据源中的所有行都经过处理。第一个行源通常称为外部表(驱动表),相应的第二个行源称为内部表。注意:使用嵌套循环连接是一种从连接结果中提取第一批记录的最快速的方法。驱动表较小、内部表连接列有唯一索引或高度可选的非唯一索引,这种场合比较适合嵌套连接。优势:快速从结果集中提取第一批记录,而不需要等待整个结果集完全确定下来。理想情况是:用户已经看到第一批记录,但是oracle还在后台提取剩余记录。 1、如果内部表的连接列上没有索引,或者索引不是高度可选,嵌套循环的效率是非常低下的。2、驱动表非常庞大,那么不建议使用嵌套循环。 select /*+ ordered */ ename,dept.deptnofrom dept,empwhere dept.deptno=emp.deptno/没有走嵌套,因为两个列上都有索引。 select /*+ ordered */ ename,dept.deptnofrom emp,deptwhere dept.deptno=emp.deptno/外部表是emp、内部表是dept。我们删除了外部表上的索引。 删除主键以后,主键索引也删除。 select /*+ ordered */ ename,dept.deptnofrom dept,empwhere dept.deptno=emp.deptno/外表是dept(驱动表)。 第一个循环返回三行记录 第二个循环返回5行记录第三个循环返回6行记录第四个循环没有返回记录一共返回1 4行记录这就是嵌套循环。驱动表 排序合并连接在排序合并连接中,oracle分别将第一个源表、第二个源表按他们各自要连接的列排序,然后将两个已经排序的源表合并。如果找到匹配的数据,就放到结果集中。在缺乏数据的选择性或者可用索引时,或者两个源表都过于庞大(超过记录数的5 %)时,排序合并连接将比嵌套循环连接更加高效。排序合并连接只能用于等价连接(where dept.deptno=emp.deptno),而不是where dept.deptnoemp.deptno。排序连接并不是一个很好的连接方式。 select /*+ ordered */ ename,dept.deptnofrom dept,empwhere dept.deptno=emp.deptno对两个表的连接列分别进行排序合并 排序合并连接需要临时内存块,用于排序。我们要尽量避免磁盘排序,保证始终使用内存排序,否则性能会很低。保证内存排序的方法是:设置足够的PGA_AGGREGATE_TARGET参数或者SGA_TARGET参数,设置哪个参数取决于是专用服务器还是共享服务器。 集群连接这是一个集群表的存储方式。集群连接实际上是嵌套连接的一种特例。如果所连接的两张行源表实际上是集群中的表。例如左面的emp和dept。并且连接是两张行源表的集群键(deptno)的等价连接,那么在oracle中就能使用集群连接。Oracle从第一张行源表中读取第一行,并在第二张行源表中使用cluster索引查找所有匹配的项。集群索引效率极高,因为两个行源表实际上存储在同一个物理块 上。集群连接有一个限制:两个行源表表必须是集群表。因此集群连接使用的很少。 散列连接HASH算法最大的好处插入和访问的速度特别快。当向集合中加入一个对象时,会调用hash算法来获得hash code,然后根据hash code分配存放位置。访问的时,根据hashcode直接找到存放位置。Oracle Hash join 是一种非常高效的join 算法,主要以CPU(hash计算)和内存空间(创建hash table)为代价获得最大的效率。Hash join一般用于大表和小表之间的连接,我们将小表构建到内存中,称为Hash cluster,大表称为probe表。Hash join具有较高效率的两个原因: 1 .Hash 查询,根据映射关系来查询值,不需要遍历整个数据结构。 2 .Mem 访问速度是Disk的万倍以上。 优化器会优选选择hash join。 两个表没有索引,全表扫描。Cost值是2 2 1,大约是一个大表的全表扫描的cost。 使用sort merge,主要消耗在大表的排序上。 消耗非常的大,主要消耗在连接上,因此嵌套连接是一种低效的方式。在给customerid建立索引后,效率降到1 1 6 K,但这也是一个惊人的cost。嵌套查询适合驱动表非常小的场合。 我们来研究hash join的基础原理:自从 oracke 7 .3 以来, oracle 提供了一种新的 join 技术,就是 hash join 。 Hash Join 只能用于相等连接,且只能在 CBO 优化器模式下。相对于 nested loop join , hash join 更适合处理大型结果集。 Hash join 不需要在驱动表上存在索引。Hash join 算法的一个基本思想就是根据小的 row sources( 称作 build input ,我们记较小的表为 S ,较大的表为 B) 建立一个可以存在于 hash area 内存中的 hash table ,然后用大的 row sources( 称作 probe input) 来探测前面所建的 hash table 。Oracle 在连接键利用一个 hash 函数将 build input 和 probe input 分割成多个不相连的分区(分别记作 S i 和 Bi ),这个阶段叫做分区阶段;然后各自相应的分区,即 Si 和 Bi 再做 Hash join ,这个阶段叫做 join 阶段。 如果内存过小,将会出现下面的情况:如果在分区后,针对某个分区所建的 hash table 还是太大的话, oracle 就采用 nested-loops hash join 。所谓的 nested-loops hash join 就是对部分 Si 建立 hash table ,然后读取所有的 Bi 与所建的 hash table 做连接,然后再对剩余的 Si 建立 hash table ,再将所有的 Bi 与所建的 hash table 做连接,直至所有的 Si 都连接完了。 这样性能将会严重降低下来。 Hash Join 算法有一个限制,就是它是在假设两张表在连接键上是均匀的,也就是说每个分区拥有差不多的数据。但是实际当中数据都是不均匀的,为了很好地解决这个问题, oracle 引进了几种技术,位图向量过滤、角色互换、柱状图,这些术语的具体意义会在后面详细介绍。我们用一个例子来解释 Hash Join 算法的原理,以及上述所提到的术语。 考虑以下两个数据集。 S=1 ,1 ,1 ,3 ,3 ,4 ,4 ,4 ,4 ,5 ,8 ,8 ,8 ,8 ,1 0 B=0 ,0 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,8 ,9 ,9 ,9 ,1 0 ,1 0 ,1 1 第一步,build input 分区。分区的个数叫做 fan-out 。 Fan-out 是由 hash_area_size 和 cluster size 来决定的。其中 cluster size 等于 db_block_size * hash_multiblock_io_count , hash_multiblock_io_count 在 oracle9 i 中是隐含参数。分区数=0 .8 *hash_area_size/(hash_multiblock_io_count*db_block_size)大的 fan-out 导致许多小的分区,影响性能,而小的 fan-out 导致少数的大的分 区,以至于每个分区不能全部存放在内存中,这也影响 hash join 的性能。 Oracle 采用内部一个 hash 函数作用于连接键上,将 S 和 B 分割成多个分区,在这里我们假设这个 hash 函数为求余函数,即 Mod(join_column_value,1 0 ) 。这样产生十个分区,如下表。 经过这样的分区之后,只需要相应的分区之间做 join 即可(也就是所谓的 partition pairs ),如果有一个分区为 NULL 的话,则相应的分区 join 即可忽略。 在将 S 表读入内存分区时, oracle 即记录连接键的唯一值,构建成所谓的位图向量,它需要占 hash area 内存的 5 % 左右。在这里即为 1 ,3 ,4 ,5 ,8 ,1 0 。 当对 B 表进行分区时,将每一个连接键上的值与位图向量相比较,如果不在其中,则将其记录丢弃。在我们这个例子中, B 表中以下数据将被丢弃 0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,9 ,9 ,9 ,9 ,9 。这个过程就是位图向量过滤。 当 S1 ,B1 做完连接后,接着对 Si,Bi 进行连接,这里 oracle 将比较两个分区,选取小的那个做 build input ,就是动态角色互换,这个动态角色互换发生在除第一对分区以外的分区上面。 第 1步:决定 fan-out 数。 分区数=0 .8 *hash_area_size/(hash_multiblock_io_count*db_block_size)第 2 步:读取部分小表 S ,采用内部 hash 函数 ( 这里称为 hash_fun_1 ) ,将连接键值映射至某个分区,同时采用 hash_fun_2 函数对连接键值产生另外一个 hash 值,这个 hash 值用于创建 hash table 用,并且与连接键值存放在一起。 第 3 步:对 build input 建立位图向量。 第 4 步:如果内存中没有空间了,则将分区写至磁盘上。 第 5 步:读取小表 S 的剩余部分,重复第三步,直至小表 S 全部读完。 第 6 步:将分区按大小排序,选取几个分区建立 hash table( 这里选取分区的原则是使选取的数量最多 ) 。 第 7 步:根据前面用 hash_fun_2 函数计算好的 hash 值,建立 hash table 。 第 8 步:读取表 B ,采用位图向量进行位图向量过滤。 第 9 步:对通过过滤的数据采用 hash_fun_1 函数将数据映射到相应的分区中去,并计算 hash_fun_2 的 hash 值。 第 1 0 步:如果所落的分区在内存中,则将前面通过 hash_fun_2 函数计算所得的 hash 值与内存中已存在的 hash table 做连接。如果所落的分区不在内存中,则将相应的值与表 S 相应的分区放在一起。 第 1 1 步:继续读取表 B ,重复第 9 步,直至表 B 读取完毕。 第 1 2 步:读取相应的 (Si,Bi) 做 hash 连接。在这里会发生动态角色互换。 第 1 3 步:如果分区过后,最小的分区也比内存大,则发生 nested- loop hash join 。 HASH快速的原因:1、对S和B表进行了分区2、连接键进行hash运算以后,根据hash code快速的插入到相应的分区中3、我们只需要对Si和Bi进行分区内部的连接即可,而这些分区内的数量是非常少的如果hash size足够的大,那么所有的连接都发生在内存中,速度非常的快。Hash join主要的消耗发生在全表扫描大表上。 Hash 连接的原理就是生成上面的一张表,然后Si和Bi进行分区内部的连接。生成这张表的过程使用了hash算法,hash值快速的定位到相应的分区中。生成这个表的过程需要消耗内存和CPU。 1 确认大表是驱动表 2 确认涉及到的表和连接键分析过了。 3 如果在连接键上数据不均匀的话,建议做柱状图。 4 如果可以,调大 hash_area_size 的大小或 pga_aggregate_target 的值。 5 Hash Join 适合于小表与大表连接、返回大型结果集的连接。 HASH_AREA_SIZE在Oracle 9 i 和以前,都是影响hash join性能的一个重要的参数。但是在1 0 g发生了一些变化。Oracle不建议使用这个参数,除非你是在MTS模式下。Oracle建议采用自动PGA管理(设置PGA_AGGREGATE_TARGET和WORKAREA_SIZE_POLICY)来替代使用这个参数。MTS的PGA中,只包含了一些栈空间信息,UGA则包含在large pool中,那么实际类似hash,sort,merge等操作都是有large pool来分配空间,large pool同时也是auto管理的,它和SGA_TARGET有关。 散列连接是CBO 做大数据集连接时的常用方式,优化器使用两个表中较小的表(或数据源)利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行。 这种方式适用于较小的表完全可以放于内存中的情况,这样总成本就是访问两个表的成本之和。排序合并连接通常情况下散列连接的效果都比排序合并连接要好,然而如果行源已经被排过序,在执行排序合并连接时不需要再排序了,这时排序合并连接的性能会优于散列连接。可以使用USE_MERGE(table_name1 table_name2 )来强制使用排序合并连接。 NESTED LOOP:对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大(大于1 万不适合),要把返回子集较小表的作为外表(CBO 默认外表是驱动表),而且在内表的连接字段上一定要有索引。当然也可以用ORDERED 提示来改变CBO默认的驱动表,使用USE_NL(table_name1 table_name2 )可是强制CBO 执行嵌套循环连接。 Hash join的主要资源消耗在于CPU(在内存中创建临时的hash表,并进行hash计算),而merge join的资源消耗主要在于此盘IO(扫描表或索引)。在并行系统中,hash join对CPU的消耗更加明显。所以在CPU紧张时,最好限制使用hash join。在绝大多数情况下,hash join效率比其他join方式效率更高:在Sort-Merge Join(SMJ),两张表的数据都需要先做排序,然后做merge。因此效率相对最较差;Nested-Loop Join(NL)效率比SMJ更高。特别是当驱动表的数据量很大(集的势高)时。这样可以并行扫描内表。 Hash join效率最高,因为只要对两张表扫描一次。 索引连接在oracle 8 i以前,必须访问表,直到单个索引包含了所有需要的信息。从oracle8 i开始,如果一组已存在的索引包含了查询所需要的所有信息,那么优化器将在索引中有选择的生成一组散列表,然后进行hash连接。不需要访问整个表就可以直接访问数据。可通过范围扫描或者快速全局扫描访问到每一个索引,而通过何种方式访问索引,主要取决于where条件。如果一个表有大量的列,这个表占用的数据块就多,这种情况下如果访问的列包含在一组索引中,那么可以采用索引连接。select ename,deptnofrom emp where deptno=2 0and ename = DUMMY;如果在ename列上和deptno列上分别建立了索引,索引扫描效果会很好。 一个案例一个表test2,数据量是1 0 0万行。全表扫描或者使用单一索引,效率都较低。 使用连接索引以后,查询性能得到了很大的提高。最理想的情况还是复合索引。复合索引的问题:复合索引的第一列必须作为查询的where限制列,否则索引没有很大的意义。因此复合索引大大的限制了where条件的灵活性。复合索引占用的数据块数太多,因此性能会比较低下。索引的好处就是:小、排序、树。 表连接的初始化参数排序合并连接和散列连接的性能将取决于特定的初始化参数。如果特定的参数设置不正确,连续的性能可能急剧下降。排序合并连接和散列连接参数当oracle执行一系列读操作(例如全表扫描)时,每次从磁盘读取多少数据块。因为排序合并连接经常牵涉到全表扫描,设置这个参数以后,在扫描大表时将降低cost。 排序连接需要对所有表源进行排序,因此需要较大的排序内存。如果排序内存不能满足排序要求,将会产生磁盘排序(内存和临时表空间交换数据)。这样排序性能将会大大的降低。同样的对于hash连接也是一样,如果因为内存不足而不能在内存中建立完整的散列表,那么性能将会大大的降低。因此我们需要设置足够的pga_aggregate_target参数。如果这个参数设置过大,那么系统会因为物理内存消耗殆尽,而发生swap的使用率增加,降低了整体的系统性能。 类别嵌套循环连接排序合并连接散列连接优化器提示USE_NL USE_MERGE USE_HASH何时使用任何连接任何连接仅用于等价连接相关资源CPU、磁盘I/O内存、临时空间内存、临时空间特点当有高选择性索引或者进行限制性搜索时效率较高,用于快速返回第一次的搜索结果当缺乏索引或者搜索条件模糊时,该类型的连接比嵌套循环连接有效。可以在有限的内存下工作当缺乏索引或者搜索条件模糊时,该类型的连接比嵌套循环连接有效。通常比排序合并快缺点当索引丢失或者查 询条件限制不够时,效率很低所有的表都需要排序,在结果没有全部找到前不返回数据为建立散列表,需要大量的内存,第一次返回结果较慢。如果在磁盘上操作速度将极其慢 双表连接:等尺寸表(CBO)SMALL1 1 0 0 0 0 rows No IndexesSMALL2 1 0 0 0 0 rows No Indexes示例1如果初始化参数设置为可以使用散列连接,oracle将使用散列连接。否则将会使用排序合并连接。访问的第一张表将会是SMALL1,对散列连接来说,这很重要,但是对于排序合并来说,没有什么意义。典型的典型的散列连接将会使用较小的表作为散列表,但是上面的两个表大小一样,因此会按照顺序使用SMALL1 .注意:需要对表继续分析,否则会得到不正确的执行计划,这是CBO的特点。如果执行计划没有按照预期的走,首先对表继续统计分析。 示例2所有的表都没有索引,并且您将使用ordered提示如果初始化参数设置为可以使用散列连接,oracle将使用散列连接。否则将会使用排序合并连接。访问的第一张表将会是SMALL1,对散列连接来说,这很重要,但是对于排序合并来说,没有什么意义。因为使用了orderd提示,因此会按照顺序使用SMALL1作为驱动表.当设置了初始化参数以后,优化器在原来使用排序合并连接的场所改为使用 散列连接。在该连接中,第一张表用于建立散列表、第二张表用作驱动表。如果使用了ordered提示,那么from后面的第一张表将作为散列表。 双表索引连接:等尺寸表(基于成本)SMALL1 1 0 0 0 0 rows Indexes on COL1SMALL2 1 0 0 0 0 rows Indexes on COL1嵌套循环连接、使用SMALL1表作为驱动表,首先根据第一个表的索引检索驱动表的记录,形成一个行源。然后使用第二个表的索引检索形成第二个行源。最后,两个行源进行嵌套连接。如果第一个行源检索的记录很少,第二个行源的连接列上有一个较好的索 引,那么速度将会非常的快。上面使用的是嵌套连接,也可以使用散列和排序连接如果加上了orderd提示,那么将会使用from后面的第一个表作为驱动表。 强制执行特殊的连接方法当为一个包含连接的查询选择执行计划时,oracle优化器考虑所有可能的连接方法和表的查询顺序。Oracle尽量估算每一个方案的成本并选择最佳的执行计划。但是因为索引策略很糟糕,有时优化器并未能选择最佳的方案。连接方法+表的访问顺序USE_NL、USE_MERGE、USE_HASH可以指定一种连接方法。ORDERED可以指定特定的连接顺序。Oracle尽量满足这些提示,但是如果实现不了,提示将会被忽略。 强制执行嵌套循环连接。a表被作为驱动表。如果a表过大,那么性能会很低下。强制使用排序合并连接。强制使用散列合并连接。 在多表连接中除去连接记录交叉表i作为三个表的连接表,一般这个表会被作为驱动表。可以尝试使用限制条件最多的表作为驱动表,这样当连接第三张表时,您从前两张表连接所获得的结果集将很小。首先是v和i进行连接,得到一个行源,然后这个行源和l进行连接。最后加上一个过滤条件。首先是i和v进行连接,得到的行源中已经没有了“已经付款的记录”,然后这个行源和下面的l进行连接。显然 这样的写法速度更快,因为在连接以前已经将多余的记录进行过滤。 在大小不同的表间进行双表连接PRODUCT 7 0 thousands rows index on product_idPRODUCT_LINES 4 million rows index on product_id一张小表和一张大表进行连接:两个索引都被限制使用,执行计划两个表全表扫描,然后进行hash join。散列表是product(较小的表)。 散列表还是product,即使from后面的表的顺序发生了变化。如果使用ordered,将会改变选择散列表的顺序。 大表加上了一个限制子句,大表将会被作为第一个访问的表。在hash连接中,将会作为散列表。第一个访问的表:或者是散列表或者是驱动表。在大表上加了一个限制条件,这个大表的返回值将会是一个较小的行源,因此将较小的表作为第一个访问的表是符合算法的。改变from后面的连接顺序以后,效果同上,除非使用了ordered提示。 注意这个地方,oracle对小表进行限制子句。但结果是:oracle依然使用大表作为第一个访问的表。因为oracle足够的聪明,既然两个product_id列相同,小表的product_id=4 4 8 8,就等同于大表的product_id=4 4 8 8 .显然这个限制条件放在大表上更为有效,可以去除大量的访问数据。因此还是会使用大表作为第一个访问的表。 三表连接在三表连接中,oracle先连接两张表,再将结果与第三张表进行连接。Emp表Dept表Orders表结果集最终结果集 select lpad( ,2 *level)|operation oper,options,object_namefrom plan_tableconnect by prior id =parent_idstart with id=1order by id/如何查看表的连接顺序,使用上面的语句即可。注意运行这个查询的时候,假设这个表中只有一个执行计划。 位图索引位图索引非常适合DSS和数据仓库。在OLTP系统中,尽量不要使用位图索引。Bitmap 索引 Key StartROWID End ROWID BitmapTableIndex Block 1 0Block 1 1Block 1 2File 3Block 1 3 对于位图索引的列,列值的数量要求较少或者中等(索引列基数较小)。前面的例子中,列的基数是4Oracle为每个唯一键创建一个位图,然后把与键值所关联的ROWID保存为位图。最多可以包括3 0列。 位图发挥最大威力的场合是:当一个表中包含了多个位图索引,Oracle就可以合并从每个位图索引得到的结果集,快速删除不必要的数据。对于较低基数的位图索引来说,位图索引的尺寸远远的小于B树索引,因此可以大大的减少IO的数量。对于非常大的表来说,在多个低基数列上建立位图索引是一个很好的选择。对于位图索引来说,即使从表中读取很多行,也会使用位图索引。例如在一个sex列上建立索引,每次从表中读取半数的数据行,但是 还是会使用位图索引。 位图索引的插入1、位图索引在批处理(单用户)操作中加载表(插入操作)方面通常比B树做得好。2、当有多个会话同时向表中插入数据行时不应该使用位图索引3、当每条记录都增加一个新值时,B-树索引要比位图索引快3倍。四个低基数列分别建立了位图索引。Oracle会使用这四个位图索引对数据进行筛选,计算出需要读取的数据行和数据块,然后进行读取。在这个过程中会涉及到位图的计算。 在B树索引中,可以实现行级锁定,但是在位图索引中,因为对ROWDI进行压缩存放(一个ROWID范围+位图),因此每次锁定的都是整个的ROWID范围,因此对表中的位图索引列进行更新的时候,并发性很差,容易导致死锁。SELECT语句不会受到这种锁定问题的影响。位图索引有很多的限制:1、基于规则的优化器不会考虑位图索引2、当执行alter table语句并修改包含位图索引列时,会使得位图索引失效3、位图索引不包含任何列数据,不能用于任何类型的完整性检查例如主键、唯一键约束4、位图索引不能被声明为唯一索引5、位图索引的最大长度为3 0注意:不要在繁忙的OLTP系统中使用位图索引 前面回忆了位图索引,我们来看一个位图索引的案例会话1没有提交。 另起一个会话。 提示:在OLTP系统中,尽量不要使用位图索引,同样包括下面的位图连接索引。位图连接索引的特点就是:1、表的连接已经存储起来,在执行表的连接的时候,直接读取位图连接索引就可以,不需要再进行连接。这样就可以节省大量的物理和内存读(连接的特点)。2、位图索引本身相对B树索引要小得多,因此性能也就高3、当列值是唯一的或者接近唯一时,应当使用B树索引,如果列值的基数特别底,可以考虑使用位图索引4、位图索引的使用不再受到行数的限制,提取比例甚至可以达到8 0 %都会采用位图索引5、对于NULL的限制条件,也会使用位图索引,因为位图中有关于NULL的列值建议通过在列上使用NOT NULL来提高位图索引的性能6、对于非等价条件,也会使用位图索引7、使用NOT NULL和定长的列可以帮助位图节省空间8、位图索引需要使用INDEX_COMBINE提示 位图连接索引在OLAP系统中,经常的进行2张或者3张表的连接,在这种环境中,使用位图连接的效果会很好。1、必须为其中一张表建立主键或者唯一约束 dept1 emp1 索引中加入两个表以及他们的连接条件,因此这个索引中已经存储了这两个表在这个连接条件基础上的连接。使用这个索引就可以省去使用这个条件进行的连接。在dept1 .deptno列上建立的索引,因此在查询中使用这个限制条件的话,将会提高查询速度。 dept1 emp1 select /*+ index(emp1 empdept_idx) */ count(*)from emp1 ,dept1where emp1 .deptno=dept1 .deptno/ 显然没有了连接的操作。上面是统计两张表的交叉行数。 位图连接索引的最佳应用1、针对非连接列的位图连接索引注意:位图索引中也存储了列数据create bitmap index emp_dept_locationon emp1 (dept1 .loc)from emp1 ,dept1where emp1 .deptno=dept1 .deptno/select emp1 .empno,emp1 .ename,dept1 .locfrom emp1 ,dept1where emp1 .deptno=dept1 .deptno/直接读取emp1表和索引就可以得到所需要的记录。不需要访问dept1表。注意:位图连接索引最大的好处是已经建立了连接,而不是上面的一点好处。如果where条件中加上对loc列 的限制,效果将会更好。 针对多列的位图连接索引create bitmap index emp_dept_locationon emp1 (dept1 .loc,dept1 .dname)from emp1 ,dept1where emp1 .deptno=dept1 .deptno/select emp1 .empno,emp1 .ename,dept1 .loc,dept1 .dnamefrom emp1 ,dept1where emp1 .deptno=dept1 .deptno/ 针对多表的位图连接索引create bitmap index emp_dept_location_mson emp1 (dept1 .loc,sales1 .marital_status)from emp1 ,dept1 ,sales1where emp1 .deptno=dept1 .deptnoand emp1 .empno=sales1 .empno/select emp1 .empno,emp1 .ename,dept1 .loc,sales1 .marital_statusfrom emp1 ,dept1 ,sales1where emp1 .deptno=dept1 .deptnoand emp1 .empno=sales1 .empno/ 使用位图索引的好处不仅仅是运行速度快,而是节省了大量的物理和内存读。对于一个糟糕的查询来说,大量的内存和物理读才是最危害的地方。、因此我们需要经常去发现系统中存在大量的物理读和内存读的SQL语句,然后对其进行调优。
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!