カーディナリティが高いほど、読み取りパフォーマンスが向上します。これは、定義上、読み取るレコードが少ないためです。
このようなクエリを処理するには:
SELECT *
FROM mytable
WHERE indexed_col = @myvalue
、エンジンは次の手順を実行する必要があります:
-
条件を満たす最初のエントリを見つけます。
これは、
B-Tree
をトラバースして行われます。 、ルートエントリから開始します。ページ全体で、
B-Tree
に従って検索が実行されます。 リンク;ページ内では、検索はバイナリ検索を使用して実行されます(キーが圧縮されている場合を除きます。圧縮されている場合は、線形検索です)。このアルゴリズムは、カーディナリティの高い列とカーディナリティの低い列の両方で同じ効率です。最初の
3
を見つける (3
とは対照的に )これらのリスト:1 2 3 4 5 6 7 8 9 10 3 3 3 3 3 3 3 3 4 4
同じ
O(log(n))
が必要です 手順。 -
キー値が変更されるまでインデックスをトラバースします。もちろん、これには線形時間が必要です。レコードが多いほど、トラバースする必要があります。
最初のレコードのみが必要な場合:
SELECT *
FROM mytable
WHERE indexed_col = @myvalue
LIMIT 1
、列のカーディナリティは読み取りパフォーマンスに影響しません。
各インデックスキーには、レコードポインタという隠された追加の値があります。これがインデックスを持つことの要点です。どのレコードを指しているのかを知る必要があります。
レコードポインタは定義上一意であるため、各インデックスキーも一意です。同じキー値を共有するインデックスエントリは、レコードポインタによって並べ替えられます。
これは、インデックスを保守しやすくするためです。他の何百万ものレコードと共有されているインデックス付き列の値を持つレコードを削除する場合は、対応するインデックスレコードも削除する必要があります。しかし、100万のインデックスレコード全体が調べられていません。代わりに、レコードポインタが追加の検索条件として使用されます。
各インデックスキーは実際には一意であるため(インデックスを一意として定義しなくても)、したがって、可能な限り最大のカーディナリティがあります。
したがって、質問に対する答えは次のとおりです。いいえ、列のカーディナリティはインデックスの書き込みパフォーマンスに影響しません。