1

以下の単純な動的選択クエリがあります

Select RELATIONSHIP 
  from DIME_MASTER 
 WHERE CIN=? AND SSN=? AND ACCOUNT_NUMBER=?

テーブルには 1,083,701 レコードがあります。このクエリの実行には 11 ~ 12 秒かかり、コストがかかります。DIME_MASTER テーブルには ACCOUNT、CARD_NUMBER INDEXES があります。クエリの実行時間が数秒未満になるように、このクエリを最適化するのを手伝ってください。

4

2 に答える 2

1

述語情報を見てください。

--------------------------------------
 1 - filter(TO_NUMBER("DIME_MASTER"."SSN")=226550956 
            AND TO_NUMBER("DIME_MASTER"."ACCOUNT_NUMBER")=4425050005218650 
            AND TO_NUMBER("DIME_MASTER"."CIN")=00335093464) 

列のタイプは NVARCHAR ですが、クエリのパラメーターは NUMBER です。
Oracle は数値を文字列にキャストする必要がありますが、キャストがうまくいかない場合があります。
オラクルと占い師は常に正しいとは限りません;)

これらのキャストは、クエリがインデックスを使用するのを防ぎます。

明示的な変換を使用してクエリを次のように書き直します。

Select RELATIONSHIP 
  from DIME_MASTER 
 WHERE CIN=to_char(?) AND SSN=to_char(?) AND ACCOUNT_NUMBER=to_char(?)

次に、次のコマンドを実行します。

exec dbms_stats.gather_table_stats( user, 'DIME_MASTER' );

クエリを実行して、新しい説明プランを表示してください。

ここに説明計画を貼り付けないでください。それらは判読できません。代わりにペーストビン
を使用し、ここにリンクのみを貼り付けてください。ありがとうございます。

この簡単な例を見てください。明示的なキャストが必要な理由を示しています。

CREATE TABLE "DIME_MASTER" ( 
  "ACCOUNT_NUMBER" NVARCHAR2(16)
);
insert into dime_master
select round( dbms_random.value( 1, 100000 )) from dual
connect by level <= 100000;
commit;
create index dime_master_acc_ix on dime_master( account_number );

explain plan for select * from dime_master
where account_number = 123;

select * from table( dbms_xplan.display );

Plan hash value: 1551952897

---------------------------------------------------------------------------------
| Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |     3 |    54 |    70   (3)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| DIME_MASTER |     3 |    54 |    70   (3)| 00:00:01 |
---------------------------------------------------------------------------------

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

   1 - filter(TO_NUMBER("ACCOUNT_NUMBER")=123)




explain plan for select * from dime_master
where account_number = to_char( 123 );

select * from table( dbms_xplan.display );
Plan hash value: 3367829596

---------------------------------------------------------------------------------------
| Id  | Operation        | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                    |     3 |    54 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| DIME_MASTER_ACC_IX |     3 |    54 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

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

   1 - access("ACCOUNT_NUMBER"=U'123')
于 2013-08-01T19:42:04.303 に答える