54

私は主に Actionscript の開発者であり、決して SQL の専門家ではありませんが、単純なサーバー側のものを開発する必要がある場合があります。というわけで、タイトルの質問については、もっと経験豊富な人に聞いてみようと思いました。

私の理解では、いくつかの異なる値を保持する列にインデックスを設定しても、あまり得はありません。ブール値を保持する列があり (実際には小さな int ですが、フラグとして使用しています)、この列はほとんどのクエリの WHERE 句で使用されています。理論上の「平均」のケースでは、レコードの値の半分は 1 になり、残りの半分は 0 になります。したがって、このシナリオでは、データベース エンジンは完全なテーブル スキャンを回避できますが、とにかく多くの行を読み取る必要があります。 (合計行/2)。

では、この列をインデックスにする必要がありますか?

記録のために、私はMysql 5を使用していますが、カーディナリティが低いことがわかっている列にインデックスを付けることが意味をなさない/しない理由についての一般的な理論的根拠にもっと興味があります。

前もって感謝します。

4

5 に答える 5

93

次の場合、インデックスはカーディナリティの低いフィールドでも役立ちます。

  1. 可能な値の 1 つが他の値と比較して非常にまれであり、それを検索する場合。

    たとえば、色盲の女性はほとんどいないため、次のクエリは次のようになります。

    SELECT  *
    FROM    color_blind_people
    WHERE   gender = 'F'
    

    に索引を付けると、おそらく恩恵を受けるでしょうgender

  2. 値が表の順序でグループ化される傾向がある場合:

    SELECT  *
    FROM    records_from_2008
    WHERE   year = 2010
    LIMIT 1
    

    ここには明確な年しかありませんが3、年が古いレコードが最初に追加される可能性が最も高い2010ため、インデックスがない場合、最初のレコードを返す前に非常に多くのレコードをスキャンする必要があります。

  3. 必要な場合ORDER BY / LIMIT:

    SELECT  *
    FROM    people
    ORDER BY
            gender, id
    LIMIT 1
    

    インデックスがなければ、afilesortが必要になります。に対していくらか最適化されていますが、LIMITそれでも完全なテーブル スキャンが必要です。

  4. インデックスがクエリで使用されるすべてのフィールドをカバーする場合:

    CREATE INDEX (low_cardinality_record, value)
    
    SELECT  SUM(value)
    FROM    mytable
    WHERE   low_cardinality_record = 3
    
  5. 必要な場合DISTINCT:

    SELECT  DISTINCT color
    FROM    tshirts
    

    MySQLを使用INDEX FOR GROUP-BYします。色が少ない場合、このクエリは数百万のレコードでも瞬時に実行されます。

    これは、カーディナリティの低いフィールドのインデックスが、カーディナリティの高いフィールドのインデックスよりも効率的であるシナリオの例です。

パフォーマンスが問題にならない場合DMLは、インデックスを作成しても安全です。

インデックスが非効率的であるとオプティマイザが判断した場合、そのインデックスは使用されません。

于 2010-01-21T22:10:45.533 に答える
10

複合インデックスにブール フィールドを含める価値があるかもしれません。たとえば、通常は日付順に並べる必要があるメッセージの大きなテーブルがあるが、ブール値のDeletedフィールドもある場合、次のようにクエリを実行することがよくあります。

SELECT ... FROM Messages WHERE Deleted = 0 AND Date BETWEEN @start AND @end

DeletedフィールドとDateフィールドに複合インデックスを設定すると、確実にメリットが得られます。

于 2010-01-21T21:55:36.457 に答える
3

私は通常、単純な「インデックスを持っている」と「持っていない」インデックスのテストを行います。私の経験では、インデックス付きの列で ORDER BY を使用するクエリでほとんどのパフォーマンスが得られます。その列に並べ替えがある場合は、インデックス作成が役立つ可能性が高くなります。

于 2010-01-21T21:50:04.223 に答える
2

私見それは有用性が限られています。ほとんどの場合、おそらくもっと役立つフラグに加えて、クエリで使用している他の基準があると思います。

50% の場合は、ベンチマークの有無にかかわらずベンチマークを行い、大きな違いがあるかどうかを確認します。

于 2010-01-21T21:51:01.413 に答える