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

一部のデータのみのOracle11インデックス

    まず、質問を正しく理解していることを確認します。

    • 高速化するSELECT .. WHERE C_D IS NULL しかし、あなたはしません NULL以外のC_Dを検索するクエリを高速化したい。
    • スペースを節約するために、インデックスに「不要な」非NULL値が含まれていないことも確認する必要があります。

    その理解が正しければ、必要なのは機能です。 索引。私は。フィールド自体ではなく、フィールド上の関数のインデックス...

    CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS
    

    ...次にクエリを実行します...

    SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
    

    ...これは...

    と同等です
    SELECT * FROM T WHERE C_D IS NULL
    

    ...ただし、インデックスを使用するため高速です:

    これにより、単一列のインデックスにはNULLが格納されないため、スペースが節約されます。また、COMPRESSを使用します インデックスにはキーが1つしか含まれないため、インデックス構造で同じキーを何度も繰り返すときにスペースを無駄にする必要はありません。

    注:Oracle 11では、関数ベースの仮想列<を作成することもできます。 / a> (CASEに基づく 上記の式)、次にその列に直接インデックスを付けてクエリを実行し、繰り返し入力する手間を省きます。

    ---編集---

    C_D IS NULLと一緒にC_Iでクエリを実行することにも関心がある場合 、できます...

    CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)
    

    ...そして(たとえば)でクエリします...

    SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
    

    ...これは...

    と同等です
    SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL
    

    ...ただし、インデックスT_IE2を使用するため、より高速です 。

    実際、これはテーブルに必要な唯一のインデックスです(主キーを「カバー」するため、C_Iだけに個別のインデックスは必要ありません)。つまり、同じROWIDが複数のインデックスに保存されることはなく、スペースを節約できます。

    注:COMPRESS インデックスT_IE2には意味がなくなりました 。

    ---編集2---

    スペースよりも単純さを重視する場合は、{C_I、C_D}に複合インデックスを作成するだけです。 Oracleは、同じタプルにNULL以外の値が少なくとも1つある限り、複合インデックスにNULL値を格納します。

    CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)
    

    これはインデックスを使用します:

    SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL
    

    以前の編集と同様に、これはテーブルに必要な唯一のインデックスです。



    1. postgresqlのRAISENOTICEからファイルに書き込む

    2. SQL Serverで先頭と末尾の空白を削除する方法– TRIM()

    3. 私のMacでのpythonmysqldberr:ライブラリがロードされていません:@ rpath / libmysqlclient.21.dylib

    4. DB接続で使用可能な行に基づいてDAGを動的に作成する