1

フィルタリングを実行し、ROWID で結合するこの非常に単純なクエリがあります。

SELECT *
FROM  BOOKING.BOOKING_GRID BG,
  BOOKING.BOOKING_STATES BS
WHERE BG.hotel=128
AND BS.ROWID =BG.BOOKINGSTATE;

計画を説明すると、次のようになります。

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1597031677                                                                                                                                                                                                                                                                                  

--------------------------------------------------------------------------------------------------                                                                                                                                                                                                           
| Id  | Operation          | Name                | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                                                                                                                                                                                                           
--------------------------------------------------------------------------------------------------                                                                                                                                                                                                           
|   0 | SELECT STATEMENT   |                     |  6137K|  1041M|       |  1763K  (1)| 05:48:27 |                                                                                                                                                                                                           
|*  1 |  HASH JOIN         |                     |  6137K|  1041M|   538M|  1763K  (1)| 05:48:27 |                                                                                                                                                                                                           
|*  2 |   INDEX UNIQUE SCAN| BOOKING_GRIDPK      |  6137K|   468M|       |   547K  (1)| 01:48:05 |                                                                                                                                                                                                           
|*  3 |    INDEX RANGE SCAN| BOOKING_GRID_INDEX5 |  6137K|       |       | 90388   (1)| 00:17:52 |                                                                                                                                                                                                           
|   4 |   TABLE ACCESS FULL| BOOKING_STATES      |   158M|    14G|       |   365K  (2)| 01:12:14 |                                                                                                                                                                                                           
--------------------------------------------------------------------------------------------------                                                                                                                                                                                                           

Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
---------------------------------------------------                                                                                                                                                                                                                                                          

   1 - access("BS".ROWID="BG"."BOOKINGSTATE")                                                                                                                                                                                                                                                                
   2 - access("BG"."HOTEL"=128)                                                                                                                                                                                                                                                                              
   3 - access("BG"."HOTEL"=128)     

BOOKING_GRID のインデックスは次のとおりです。

BOOKING BOOKING_GRIDPK  UNIQUE  VALID   IOT - TOP   N   NO      NO  HOTEL, DAY, BOOKINGSTATE
BOOKING BOOKING_GRID_UNIQ   UNIQUE  VALID   NORMAL  N   NO      NO  HOTEL, DAY, BOOKING, VALIDITYSTART
BOOKING BOOKING_GRID_INDEX5 NONUNIQUE   VALID   NORMAL  N   NO      NO  HOTEL, BOOKINGSTATUS, ISDAYUSE, DAY
BOOKING BOOKING_GRID_INDEX7 NONUNIQUE   VALID   NORMAL  N   NO      NO  HOTEL, BOOKING, VALIDITYSTART
BOOKING BOOKING_GRID_INDEX10    NONUNIQUE   VALID   NORMAL  N   NO      NO  HOTEL, ISDAYUSE, BOOKINGSTATUS, DAY

BOOKING_STATES のインデックスは次のとおりです。

BOOKING BOOKING_STATES_PK   UNIQUE  VALID   NORMAL  N   NO      NO  HOTEL, BOOKING, VALIDITYSTART   
BOOKING BOOKING_STATES_INDEX2   NONUNIQUE   VALID   NORMAL  N   NO      NO  HOTEL, YIELDROOMTYPE, BOOKEDROOMTYPE, ROOMTYPE  
BOOKING BOOKING_STATES_BOOKING  NONUNIQUE   VALID   NORMAL  N   NO      NO  HOTEL, BOOKING, BOOKINGSTATUS   
BOOKING BOOKING_NOSEGMENT_INDEX NONUNIQUE   VALID   FUNCTION-BASED NORMAL   N   NO  ENABLED NO  SYS_NC00034$    TO_NUMBER(DECODE(TO_CHAR("MARKETSEGMENT"),NULL,DECODE("BOOK",0,NULL,TO_CHAR(DECODE("ISDAYUSE",'N',DECODE("ISSHARED",'N',DECODE("BOOKINGSTATUS",'B',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"),'I',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"),'W',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"))))))))
BOOKING BOOKING_NORATE_CODE_INDEX   NONUNIQUE   VALID   FUNCTION-BASED NORMAL   N   NO  ENABLED NO  SYS_NC00033$    TO_NUMBER(DECODE(TO_CHAR("RATECODE"),NULL,DECODE("BOOK",0,NULL,TO_CHAR(DECODE("ISDAYUSE",'N',DECODE("ISSHARED",'N',DECODE("BOOKINGSTATUS",'B',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"),'I',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"),'W',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"))))))))
BOOKING BOOKING_NOBOOKINGTYPE_INDEX NONUNIQUE   VALID   FUNCTION-BASED NORMAL   N   NO  ENABLED NO  SYS_NC00032$    TO_NUMBER(DECODE(TO_CHAR("BOOKINGTYPE"),NULL,DECODE("BOOK",0,NULL,TO_CHAR(DECODE("ISDAYUSE",'N',DECODE("ISSHARED",'N',DECODE("BOOKINGSTATUS",'B',"HOTEL"*10000+LEAST("DEPARTURE","VALIDITYEND"))))))))
BOOKING BOOKING_STATES_BOOKING_TYPE NONUNIQUE   VALID   NORMAL  N   NO      NO  HOTEL, BOOKINGTYPE, ISDAYUSE, BOOKINGSTATUS 
BOOKING BOOKING_STATES_CANCEL_INDEX NONUNIQUE   VALID   FUNCTION-BASED NORMAL   N   NO  ENABLED NO  SYS_NC00035$, SYS_NC00036$  DECODE("BOOKINGSTATUS",'c',"HOTEL",'C',"HOTEL")
BOOKING BOOKING_STATES_CANCEL_INDEX NONUNIQUE   VALID   FUNCTION-BASED NORMAL   N   NO  ENABLED NO  SYS_NC00035$, SYS_NC00036$  DECODE("BOOKINGSTATUS",'c',"CANCELREASON",'C',"CANCELREASON")

私は2つのことを理解していません:

  1. hotel=128でフィルタリングする前に、オラクルが参加する方が速いと判断するのはなぜですか?
  2. 「TABLE ACCESS BY USER ROWID」を使用できる場合にハッシュ結合を使用する理由

奇妙なことに、hotel=201 でまったく同じリクエストを実行すると、まったく問題ありません。

PLAN_TABLE_OUTPUT                                                                                                                                                                                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 4251203092                                                                                                                                                                                                                                                                                  

---------------------------------------------------------------------------------------------------                                                                                                                                                                                                          
| Id  | Operation                   | Name                | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                          
---------------------------------------------------------------------------------------------------                                                                                                                                                                                                          
|   0 | SELECT STATEMENT            |                     |   591K|   100M|   643K  (1)| 02:07:12 |                                                                                                                                                                                                          
|   1 |  NESTED LOOPS               |                     |   591K|   100M|   643K  (1)| 02:07:12 |                                                                                                                                                                                                          
|*  2 |   INDEX UNIQUE SCAN         | BOOKING_GRIDPK      |   591K|    45M| 52686   (1)| 00:10:25 |                                                                                                                                                                                                          
|*  3 |    INDEX RANGE SCAN         | BOOKING_GRID_INDEX5 |   591K|       |  8707   (1)| 00:01:44 |                                                                                                                                                                                                          
|   4 |   TABLE ACCESS BY USER ROWID| BOOKING_STATES      |     1 |    98 |     1   (0)| 00:00:01 |                                                                                                                                                                                                          
---------------------------------------------------------------------------------------------------                                                                                                                                                                                                          

Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
---------------------------------------------------                                                                                                                                                                                                                                                          

   2 - access("BG"."HOTEL"=201)                                                                                                                                                                                                                                                                              
   3 - access("BG"."HOTEL"=201)  

そこで何が起こっているかについて何か考えはありますか?

ありがとうございました、

ルノー

4

1 に答える 1

1

実行パスが異なる理由は、hotel=128 では約 600 万行あり、hotel=201 では 591,000 行しかないと Oracle が考えているためです。より大きな中間セットの場合、オラクルはネストされたループよりもハッシュ結合を選択しました。

私が得られないのはこれです:

AND BS.ROWID =BG.BOOKINGSTATE;

Oracle形式のROWIDをBOOKINGSTATEという列に保存していますか???


OK、BOOKINGSTATE に実際に Oracle ROWID が含まれていることを確認したので、NESTED LOOP 結合ではなく HASH JOIN を取得していると私が言う理由は次のとおりです。

まず、Oracle が行を読み取るとき、一度に行を読み取るだけでなく、一度にブロックを読み取ります。したがって、TABLE ACCESS BY USER ROWID ルックアップを使用して NESTED LOOP 結合を実行するには、BOOKING_GRID で行を検索し、その ROWID を持つ BOOKING_STATES の行を含むブロックを読み取ります。問題は、後でブロック内に以前に読み取られた行 ID を持つ別の行がある場合、そのブロックを再読み取りして (確かに、キャッシュされている可能性があります)、別の行を取得することです。「ブロックを開いて行を取得し、ボックスを閉じて....後で同じボックスをもう一度開いて、別の行を取得し、ボックスを閉じて、次のボックスに進む」のようなものです。

一方、ハッシュ結合は次のとおりです。 - 小さい方のセット (この場合、hotel=128 の BOOKING_GRID の行) の行を並べ替え、それらをメモリに配置します - 完全なテーブル スキャン BOOKING_STATES - そしてここにキッカーがあります - マルチブロック読み取りの使用. 一度に多くのブロックを読み取り、ブロック内のすべての行を後で再読み取りする必要なく処理します。「ボックスを開き、ボックス内のすべての行を処理してから、ボックスを閉じる」ようなものです。

(上記の詳細については、http://docs.oracle.com/cd/B28359_01/server.111/b28274/optimops.htm、特に次のセクションを参照してください:

  • 11.5.1 全表スキャン
  • 11.5.3.1 行ではなくブロックのI/Oの評価
  • 11.6.3 ネストされたループ結合
  • 11.6.4 ハッシュ結合)

ところで、2 つのインデックスを使用して "access("BG"."HOTEL"=128)" ステップを 2 回実行しているのは少し興味深いです。BOOKING_GRIDPK および BOOKING_GRID_INDEX5 インデックスはどのように定義されているのでしょうか。両方のテーブルのすべての列を要求していますが、プランが BOOKING_GRID テーブルに触れることはありません。)

于 2013-09-04T16:37:15.243 に答える