sql >> データベース >  >> RDS >> Oracle

インデックスの統計を収集するか、作成を削除しますか?

    違いは、統計を収集すると現在のインデックスに関するメタデータが更新されるのに対し、インデックスを削除して再作成することは、インデックスを削除して再作成することです。

    おそらく、実際の例で違いを理解するのは簡単です。それでは、テーブルとインデックスを作成しましょう:

    SQL> create table t23 
      2  as select object_id as id, object_name as name from user_objects 
      3  /
    
    Table created.
    
    SQL> create index i23 on t23(id)
      2  /
    
    Index created.
    
    SQL> select o.object_id, i.last_analyzed, i.distinct_keys
      2  from user_objects o
      3       join user_indexes i
      4            on (i.index_name = o.object_name)
      5  where o.object_type = 'INDEX'
      6  and i.index_name = 'I23'
      7  /
    
     OBJECT_ID CREATED              LAST_ANALYZED        DISTINCT_KEYS
    ---------- -------------------- -------------------- -------------
        116353 23-NOV-2013 00:15:39 23-NOV-2013 00:15:39           167
    
    1 row selected.
    
    SQL> 
    

    11g以降、インデックスを作成すると、Oracleは自動的に統計を収集します。したがって、インデックスの作成と最後の分析は同じ日時を示します。以前のバージョンでは、インデックスを作成した後、統計を明示的に収集する必要がありました。 詳細

    次に、いくつかのデータを追加して統計を更新します:

    SQL> insert into t23 values (9999, 'TEST1')
      2  /
    
    1 row created.
    
    SQL> insert into t23 values (-8888, 'TEST 2')
      2  /
    
    1 row created.
    
    SQL> exec dbms_stats.gather_index_stats(user, 'I23') 
    
    PL/SQL procedure successfully completed.
    
    SQL> select o.object_id, i.last_analyzed, i.distinct_keys
      2  from user_objects o
      3       join user_indexes i
      4            on (i.index_name = o.object_name)
      5  where o.object_type = 'INDEX'
      6  and i.index_name = 'I23'
      7  /
    
     OBJECT_ID CREATED              LAST_ANALYZED        DISTINCT_KEYS
    ---------- -------------------- -------------------- -------------
        116353 23-NOV-2013 00:15:39 23-NOV-2013 00:26:28           169
    
    1 row selected.
    
    SQL> 
    

    これで、統計に関連するメタデータが変更されましたが、インデックスは同じデータベースオブジェクトです。一方、インデックスを削除して再作成すると、新しいデータベースオブジェクトが取得されます。

    SQL> drop index i23
      2  /
    
    Index dropped.
    
    SQL> create index i23 on t23(id) 
      2  /
    
    Index created.
    
    SQL> select o.object_id, i.last_analyzed, i.distinct_keys
      2  from user_objects o
      3       join user_indexes i
      4            on (i.index_name = o.object_name)
      5  where o.object_type = 'INDEX'
      6  and i.index_name = 'I23'
      7  /
    
     OBJECT_ID CREATED              LAST_ANALYZED        DISTINCT_KEYS
    ---------- -------------------- -------------------- -------------
        116354 23-NOV-2013 00:27:50 23-NOV-2013 00:27:50           169
    
    1 row selected.
    
    SQL> 
    

    通常の操作では、インデックスを削除して再作成する必要はほとんどありません。これは、非常に大量のデータをロードする場合や、非常にまれにインデックスが破損する場合に適した手法です。インターウェブは、パフォーマンス上の理由からインデックスの定期的な再構築を推奨するサイトを引き続きスローします(スキューされたインデックスを「リバランス」すると言われています)が、これらのサイトは長期的なメリットを証明するベンチマークを生成せず、確かに時間と再構築の演習によってCPUサイクルが無駄になります。

    インデックスの再構築には、統計の更新よりも多くの作業が必要です。再構築にはサブタスクとして統計を収集することが含まれるため、明らかに真実です。問題は、インデックスを削除して後で再作成するよりも、インデックスが配置されているテーブルに対してバルクDMLを実行する方が効率的かどうかです。インデックスのないテーブルにデータをロードし、後でそれらを再作成する方が速い場合があります。

    ここには厳格なルールはありません。インデックスの数、テーブル全体のサイズに対する影響を受ける行の割合、リレーショナル整合性制約を適用するためにインデックスが必要かどうかなどによって異なります。操作間にも大きな違いがあります。WHERE句に必要なインデックスと、更新がインデックス付き列に影響するかどうかに応じて、一括挿入のインデックスを削除し、更新のために保持することもできます。

    つまり、独自の特定のシナリオをベンチマークする必要があります。これは、パフォーマンスに関する質問の答えになることがよくあります。




    1. 実行時間の長いOracleDBクエリのシミュレーション

    2. OracleANSI結合でのUSINGとONの混合

    3. postgresqlで緯度と経度で最寄りの場所を見つけます

    4. LOAD DATA LOCAL INFILEを使用してmysqlにCSVインポートが成功した後、SQLクエリの結果が表示されない