インデックスの失効のいくつかの原因

2467 ワード

1.暗黙型変換によりインデックスが失効する.この点は重視すべきである.開発中によく犯す間違いでもある.
テーブルのフィールドtu_mdnはvarchar 2(20)として定義されていますが、クエリ時にこのフィールドをnumberタイプとしてwhere条件でOracleに渡すと、インデックスが失効します.
     :select * from test where tu_mdn=13333333333;

     :select * from test where tu_mdn='13333333333';

2.インデックス列を演算するとインデックスが無効になります.インデックス列を演算するには(+、-、*、/、!など)
      :select * from test where id-1=9;

      :select * from test where id=10;

3.Oracle内部関数を使用すると、インデックスが無効になります.このような場合には、関数ベースのインデックスを作成する必要がある.
      :select * from test where round(id)=10;   ,  id          
  
     :        ,create index test_id_fbi_idx on test(round(id));
             select * from test where  round(id)=10;           

4.以下の使用はインデックスを失効させ、使用を避けるべきである.
  • a.使用<>、not in、not exist、!=
  • b. like "%_"パーセンテージ番号は前(インデックス作成時にreverse(columnName)という方法で処理できる)
  • c.複合インデックス内の第1の位置でないインデックス列を単独で参照する.オプティマイザは、常にインデックスの最初のカラムを使用する必要があります.インデックスが複数のカラムに確立されている場合、最初のカラムがwhere句で参照されている場合にのみ、インデックスの使用を選択します.
  • d.文字型フィールドが数字の場合where条件に引用符を付けない.
  • e.変数がtimes変数である、テーブルのフィールドがdate変数である場合.あるいは逆の状況.

  • 5.空の変数値を比較演算子(シンボル)と直接比較しないでください.
    変数が空の場合は、IS NULLまたはIS NOT NULLを使用して比較するか、ISNULL関数を使用します.
    6.SQLコードで二重引用符を使用しないでください.
    文字定数は単一引用符を使用するためです.オブジェクト名を限定する必要がない場合は、(ANSI SQL規格ではない)カッコを使用して名前を囲むことができます.
    7.インデックスが存在する表領域とデータが存在する表領域をそれぞれ異なるディスクchunkに設定することで、インデックスクエリの効率化に役立ちます.
    8.Oracleでデフォルトで使用されている代価ベースのSQLオプティマイザ(CBO)は統計に非常に依存しており、統計が正常でないと、データベース・クエリーでインデックスが使用されないか、誤ったインデックスが使用されない可能性があります.
    一般的に、Oracleの自動タスクには統計を更新する文が含まれていますが、テーブル・データに大きな変化(20%を超える)が発生した場合は、すぐに統計を手動で更新することも考えられます.たとえば、analyze table abc compute statisticsですが、統計の更新にはシステム・リソースがかかるので、システムの空き時間に実行することをお勧めします.
    9.Oracleでは、1つのテーブルに対して1つのインデックスのみが使用されます.
    そのため、インデックスが多すぎると、Oracleで誤ったインデックスが使用され、クエリーの効率が低下する場合があります.たとえば、テーブルにインデックス1(Policyno)とインデックス2(classcode)があり、クエリー条件がpolicyno=‘xx’and classcode=‘xx’の場合、インデックス1の使用に比べてクエリー効率が著しく低下するインデックス2が使用される可能性があります.
    10.パーティションインデックスを優先し、可能な限り使用します.
    11.条件にorがある場合、条件付きインデックスがあっても使用されません(これもorをできるだけ少なく使う理由です)
    12.複数のカラム・インデックスの場合、使用する第1の部分ではない場合、インデックスは使用されません.
    13.mysqlがインデックスを使用するよりも全テーブルスキャンを使用するほうが速いと推定した場合、インデックスは使用しません.
    また、インデックスの使用状況を表示するには、次の文を使用します.
    show status like ‘Handler_read%';
    次の点に注意してください.
    handler_read_keyこの値が高ければ高いほど、インデックスを使用してクエリされた回数を表す
    handler_read_rnd_nextこの値が高いほど、クエリが非効率であることを示します.