Perfil de haiOracle & StarcraftBlogListas Herramientas Ayuda

Blog


    23 junio

    and_equal,index_join,index_combine

    and_equal,index_join,index_combine这三种都是oracle利用索引关联获得数据的方法,三者的目的都是为了最大限度的利用索引,减少回表的代价.但是三者的实现方法是有区别的,下面一一来分析.
    and_equal:
    这种方式需要查询条件里面包括所有索引列,然后取得每个索引中得到的rowid列表,然后对这些列表做merge join,过滤出相同的rowid后再去表中获取数据或者直接从索引中获得数据.and_equal有一些限制,比如它只对单列索引有效,只对非唯一索引有效,使用到的索引不能超过5个,查询条件只能是"=".在10g中,and_equal已经被废弃了,只能通过hint才能生效.
    create table test as select * from dba_objects;
    create index ind_test_owner on test(owner);
    create index ind_test_object_name on  test(object_name);

    SQL 10G>select/*+ and_equal(test ind_test_owner ind_test_object_name)*/ owner,object_name from test where owner='test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    -------------------------------------------------------------------------------
    | Id  | Operation         | Name                 | Rows  | Bytes | Cost (%CPU)|
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |                      |     1 |    29 |     2   (0)|
    |*  1 |  AND-EQUAL        |                      |       |       |            |
    |*  2 |   INDEX RANGE SCAN| IND_TEST_OWNER       |     1 |       |     1   (0)|
    |*  3 |   INDEX RANGE SCAN| IND_TEST_OBJECT_NAME |     2 |       |     1   (0)|
    -------------------------------------------------------------------------------
    如果查询条件只包含owner

    SQL 10G>select/*+ and_equal(test ind_test_owner ind_test_object_name)*/ owner,object_name from test where owner='test';
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------
    | Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                |     1 |    29 |     2   (0)|
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST           |     1 |    29 |     2   (0)|
    |*  2 |   INDEX RANGE SCAN          | IND_TEST_OWNER |     1 |       |     1   (0)|
    -----------------------------------------------------------------------------------
    修改owner,object_name为非空
    alter table test modify(owner not null);
    alter table test modify(object_name not null);

    SQL 10G>select/*+ and_equal(test ind_test_owner ind_test_object_name)*/ owner,object_name from test where owner='test';
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------
    | Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                |     1 |    29 |     2   (0)|
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST           |     1 |    29 |     2   (0)|
    |*  2 |   INDEX RANGE SCAN          | IND_TEST_OWNER |     1 |       |     1   (0)|
    -----------------------------------------------------------------------------------
    效果一样
    查询条件是">"的情况
    SQL 10G>select/*+ and_equal(test ind_test_owner ind_test_object_name)*/ owner,object_name,object_type from test where owner>'test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name                 | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                      |     1 |    40 |     2   (0)|
    |*  1 |  TABLE ACCESS BY INDEX ROWID| TEST                 |     1 |    40 |     2   (0)|
    |*  2 |   INDEX RANGE SCAN          | IND_TEST_OBJECT_NAME |     2 |       |     1   (0)|
    -----------------------------------------------------------------------------------------
    查询条件是in的情况
    SQL 10G>select/*+ and_equal(test ind_test_owner ind_test_object_name)*/ owner,object_name,object_type from test where owner in('test','dba') and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name                 | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                      |     1 |    40 |     2   (0)|
    |*  1 |  TABLE ACCESS BY INDEX ROWID| TEST                 |     1 |    40 |     2   (0)|
    |*  2 |   INDEX RANGE SCAN          | IND_TEST_OBJECT_NAME |     2 |       |     1   (0)|
    -----------------------------------------------------------------------------------------

    再来看一下回表的情况
    SQL 10G>select/*+ and_equal(test ind_test_owner ind_test_object_name)*/ owner,object_name,object_type from test where owner='test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name                 | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                      |     1 |    40 |     2   (0)|
    |*  1 |  TABLE ACCESS BY INDEX ROWID| TEST                 |     1 |    40 |     2   (0)|
    |   2 |   AND-EQUAL                 |                      |       |       |            |
    |*  3 |    INDEX RANGE SCAN         | IND_TEST_OWNER       |     1 |       |     1   (0)|
    |*  4 |    INDEX RANGE SCAN         | IND_TEST_OBJECT_NAME |     2 |       |     1   (0)|
    -----------------------------------------------------------------------------------------
    先通过and_equal取得rowid列表,然后从表中返回数据.
     
    index_join:
    index join顾名思义是对index进行关联,oracle通过hash index join的方式实现了避免对表的访问.所有的数据都从索引中直接获得.它不受查询条件影响,可以是唯一索引,也可以是多列索引.
    SQL 10G>select/*+ index_join(test ind_test_owner ind_test_object_name)*/ owner,object_name from test where owner='test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    --------------------------------------------------------------------------------
    | Id  | Operation          | Name                 | Rows  | Bytes | Cost (%CPU)|
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |                      |     1 |    29 |     3  (34)|
    |*  1 |  VIEW              | index$_join$_001     |     1 |    29 |     3  (34)|
    |*  2 |   HASH JOIN        |                      |       |       |            |
    |*  3 |    INDEX RANGE SCAN| IND_TEST_OWNER       |     1 |    29 |     1   (0)|
    |*  4 |    INDEX RANGE SCAN| IND_TEST_OBJECT_NAME |     1 |    29 |     1   (0)|
    --------------------------------------------------------------------------------
    可以不带查询条件,只不过由index range scan变成了index fast full scan
    SQL 10G>select/*+ index_join(test ind_test_owner ind_test_object_name)*/ owner,object_name from test
      2  ;
    Execution Plan
    ----------------------------------------------------------
    ------------------------------------------------------------------------------------
    | Id  | Operation              | Name                 | Rows  | Bytes | Cost (%CPU)|
    ------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT       |                      | 51984 |  1472K|   478   (2)|
    |   1 |  VIEW                  | index$_join$_001     | 51984 |  1472K|   478   (2)|
    |*  2 |   HASH JOIN            |                      |       |       |            |
    |   3 |    INDEX FAST FULL SCAN| IND_TEST_OWNER       | 51984 |  1472K|   153   (2)|
    |   4 |    INDEX FAST FULL SCAN| IND_TEST_OBJECT_NAME | 51984 |  1472K|   322   (1)|
    ------------------------------------------------------------------------------------

    如果不是所有数据都能从索引获得,那么将不会使用index join
    SQL 10G>select/*+ index_join(test ind_test_owner ind_test_object_name)*/ owner,object_name,object_type from test where owner='test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------
    | Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                |     1 |    40 |     2   (0)|
    |*  1 |  TABLE ACCESS BY INDEX ROWID| TEST           |     1 |    40 |     2   (0)|
    |*  2 |   INDEX RANGE SCAN          | IND_TEST_OWNER |     1 |       |     1   (0)|
    -----------------------------------------------------------------------------------

    index_combine:
    index combine最早是用在bitmap index上的,在9i开始oracle默认可以使用在btree索引上,这是由_b_tree_bitmap_plans参数来控制的.oracle将btree索引中获得的rowid信息通过BITMAP CONVERSION FROM ROWIDS的步骤转换成bitmap进行匹配,然后匹配完成后通过BITMAP CONVERSION TO ROWIDS再转换出rowid获得数据或者回表获得数据.
     
    SQL 10G>select/*+ index_combine(test ind_test_owner ind_test_object_name)*/ owner,object_name from test where owner='test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    ---------------------------------------------------------------------------------------------
    | Id  | Operation                       | Name                 | Rows  | Bytes | Cost (%CPU)|
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                |                      |     1 |    29 |     2   (0)|
    |   1 |  BITMAP CONVERSION TO ROWIDS    |                      |     1 |    29 |     2   (0)|
    |   2 |   BITMAP AND                    |                      |       |       |            |
    |   3 |    BITMAP CONVERSION FROM ROWIDS|                      |       |       |            |
    |*  4 |     INDEX RANGE SCAN            | IND_TEST_OWNER       |       |       |     1   (0)|
    |   5 |    BITMAP CONVERSION FROM ROWIDS|                      |       |       |            |
    |*  6 |     INDEX RANGE SCAN            | IND_TEST_OBJECT_NAME |       |       |     1   (0)|
    ---------------------------------------------------------------------------------------------
    回表取数据的情况
    SQL 10G>select/*+ index_combine(test ind_test_owner ind_test_object_name)*/ owner,object_name,object_type from test where owner='test' and object_name='test';
    Execution Plan
    ----------------------------------------------------------
    ----------------------------------------------------------------------------------------------
    | Id  | Operation                        | Name                 | Rows  | Bytes | Cost (%CPU)|
    ----------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                 |                      |     1 |    40 |     2   (0)|
    |   1 |  TABLE ACCESS BY INDEX ROWID     | TEST                 |     1 |    40 |     2   (0)|
    |   2 |   BITMAP CONVERSION TO ROWIDS    |                      |       |       |            |
    |   3 |    BITMAP AND                    |                      |       |       |            |
    |   4 |     BITMAP CONVERSION FROM ROWIDS|                      |       |       |            |
    |*  5 |      INDEX RANGE SCAN            | IND_TEST_OWNER       |       |       |     1   (0)|
    |   6 |     BITMAP CONVERSION FROM ROWIDS|                      |       |       |            |
    |*  7 |      INDEX RANGE SCAN            | IND_TEST_OBJECT_NAME |       |       |     1   (0)|
    ----------------------------------------------------------------------------------------------
    不带查询条件的情况,index combine将不被使用
    SQL 10G>select/*+ index_combine(test ind_test_owner ind_test_object_name)*/ owner,object_name from test
      2  ;
    Execution Plan
    ----------------------------------------------------------
    -----------------------------------------------------------------------------------
    | Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)|
    -----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |                | 51984 |  1472K|  1480   (1)|
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST           | 51984 |  1472K|  1480   (1)|
    |   2 |   INDEX FULL SCAN           | IND_TEST_OWNER | 51984 |       |   123   (2)|
    -----------------------------------------------------------------------------------
    index_combine会是and_equal的很好的替代者,随着and_equal的退出,index_combine将更多得被我们看到.

    Comentarios (9)

    Espera...
    El comentario que has escrito es demasiado largo. Acórtalo.
    No has escrito nada. Vuelve a intentarlo.
    No se puede agregar tu comentario en este momento. Vuelve a intentarlo más tarde.
    Para agregar un comentario, necesitas permiso de tus padres. Pedir permiso
    Tus padres han desactivado los comentarios.
    No se puede eliminar tu comentario en este momento. Vuelve a intentarlo más tarde.
    Has superado el número máximo de comentarios que se puede dejar en un día. Vuelve a intentarlo en 24 horas.
    Se ha deshabilitado la capacidad de tu cuenta de dejar comentarios porque nuestros sistemas indican que podrías estar enviando correo no solicitado a otros usuarios. Si crees que tu cuenta se ha deshabilitado por error, ponte en contacto con el servicio de soporte técnico de Windows Live.
    Para terminar de dejar tu comentario, realiza la siguiente comprobación de seguridad.
    Los caracteres que escribas en la comprobación de seguridad deben coincidir con los de la imagen o el audio.

    Para agregar un comentario, inicia sesión con tu cuenta de Windows Live ID (si utilizas Hotmail, Messenger o Xbox LIVE, ya tienes una cuenta de Windows Live ID). Iniciar sesión


    ¿No tienes una cuenta de Windows Live ID? Regístrate

    28 Ago
    Sin nombreescribió:
    Wan Moshou game, to (wow power leveling) site to buy the cheapest gold coins! To (wow gold) for the best Dailian upgrade!
    17 Sep
    29 Ago
    Sin nombreescribió:
    It's rather amazing how fast this innovation is moving. ffxi gilEven to keep the like of myself who are deeply involved in the industry to go and see the improvement and every element that are taking place wow goldon a yearly basis is quite fantastic. wow goldOf course one of the driving factors of this business is the exponential increase in processor performance. There is no doubt that the magic of maple story mesoschip capability has delivered through the advance maplestory mesosin microprocessor allows us to think of application which never would have been possible before. The PC industry is one of maple story mesothe few industries that can deliver lower price equipment wow goldat the same time as improving the capabilities. The storage systems are now delivering Gigabyte of storage as the standard capability. wow goldOver 80 million of PCs are being sold a year. wow goldAnd the server market, the higher performance machines that these PCs networked with,wow gold are the fastest growing part of this business.wow gold The performance of those servers is increasing notwow gold only because the individual processors are faster, but also wow goldbecause we are using multiple-processor machines,wow gold so called SMP designs and clustering nodes together... Great chips, systems developers, wow goldpartners who are sponsoring this event, making this allwow gold possible. There is an incredible opportunity for developers. The applications that are written today will sell to an even larger base of machines out in the market. There is a wow goldlot that we're doing to increase the work of good developers-make sure they understand where the PC is going and how tools can help them now, more and more marketing aoc goldtype of activities making sure they got in with the customers. This is something that we are going to increase year aoc goldafter year.
    29 Ago
    Sin nombreescribió:

    Amberdigital Branch,Southern Stars Enterprises Co is specializing in the development and manufacturing of screen advertisings, digital sign, digital signages and LCDs. Established in 1996, we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us
    Southern Stars Enterprises Co (Hong Kong Office)
    Add:3 Fl, No.2, Lane 2, Kam Tsin Tsuen, Sheung Shui, Hong Kong
    Tel:+852 2681 4099
    Fax:+852 2681 4586

    Southern Stars Enterprises Co (Shenzhen Office)
    Add:DE, 16/F, Building 2, Nanguo Tower, Sungang Road, Shenzhen, China
    Tel:+86 755 2592 9100
    Fax:+86 755 2592 7171

    E-mail:sstar@netvigator.com
    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[ci

    28 Ago
    9 Ago
    30 Julio
    wenming wangescribió:
    踩踩
    28 Junio
    banky1 wang1escribió:
    你这个强人.又开始研究拉.半年没看到你的更新了。..
     
    23 Junio

    Vínculos de referencia

    La dirección URL del vínculo de referencia de esta entrada es:
    http://wzwanghai.spaces.live.com/blog/cns!56626E237AFBD116!319.trak
    Weblogs que hacen referencia a esta entrada
    • Ninguno