2009-04-16 6 views
8

新しいインデックスを追加すると、MySQLのインデックスのカーディナリティが変更されないのはなぜですか?次のように私は私のMySQLデータベーステーブルの1つにFULLTEXTインデックスを追加した

ALTER TABLE members ADD FULLTEXT(about,fname,lname,job_title); 

問題がphpMyAdminのを使用していることである私は私の新しいインデックスのカーディナリティを見ることができるだけでです。これはインデックスが使用されないことを意味しますか?

私はanalyzeテーブルコマンドを実行しましたが、何もしていないようです。インデックスフィールドの

analyze table members 

各タイプはMyISAMテーブルのvarchar(100)、VARCHAR(100)、テキスト、VARCHAR(200)及び使用されるエンジンであり、テーブルは、すべてのユニークな、約30,000行を有します。私のMySQLバージョンは5.0.45です。

何か間違っていますか?

答えて

13

テーブル内に1行しかない場合は、インデックスのカーディナリティはもちろん1でなければなりません。一意の値の数を数えるだけです。

ハッシュのようなバケットに基づくルックアップテーブルと考えると、カーディナリティはバケットの数です。

これはどのように動作するのですか?列のセット(a,b,c,d)にインデックスを作成すると、データベースはテーブル内のすべての行を処理し、各行に対して4列の順序付き四重項を調べます。のは、あなたのテーブルは次のようになりましょう:

a b c d e 
-- -- -- -- -- 
1 1 1 1 200 
1 1 1 1 300 
1 2 1 1 200 
1 3 1 1 200 

だから何データベースを見てすることはちょうど4列(A、B、C、D)である:

a b c d 
-- -- -- -- 
1 1 1 1 
1 2 1 1 
1 3 1 1 

は唯一の3つのユニークながあることを参照してください。行が残った?それらはバケツになりますが、それに戻ります。実際には、テーブル内の各行のレコードIDまたは行識別子もあります。だから、私たちの元のテーブルは次のようになります。私たちは(A、B、C、D)の唯一の4列を見たとき

(row id) a b c d e 
-------- -- -- -- -- -- 
00000001 1 1 1 1 200 
00000002 1 1 1 1 300 
00000003 1 2 1 1 200 
00000004 1 3 1 1 200 

だから、私たちは本当に行IDでも見ている:

(row id) a b c d 
-------- -- -- -- -- 
00000001 1 1 1 1 
00000002 1 1 1 1 
00000003 1 2 1 1 
00000004 1 3 1 1 

しかし、我々はによって(A、B、C、D)とない行IDで検索をしたいので、私たちはこのようなものを生成:

(a,b,c,d) (row id) 
--------- -------- 
1,1,1,1 00000001 
1,1,1,1 00000002 
1,2,1,1 00000003 
1,3,1,1 00000004 

そして最後に、私たちのグループのすべての行の行IDを同値(a、b、c、d)の値が一緒にあるもの:

(a,b,c,d) (row id) 
--------- --------------------- 
1,1,1,1 00000001 and 00000002 
1,2,1,1 00000003 
1,3,1,1 00000004 

ご覧ください。 (1,1,1,1)(1,2,1,1)と(1,3,1,1)である(a、b、c、d)の値はルックアップテーブルのキーになっています元のテーブルの行に挿入します。

実際、これは実際には起こっていませんが、インデックスの「素朴な」(すなわち直進的な)実装がどのように行われるかについての良い考えがあります。

しかし、最終的には、カーディナリティはインデックス内にいくつのユニークな行があるかを測定するだけです。この例では、ルックアップテーブルのキーの数は3でした。

希望に役立ちます!

+0

インデックス情報ありがとうございます。非常によく説明されています。私のインデックスの基数は、30000行があり、ほぼすべてのメンバーが異なる名前を持っていることを考えると、1以上でなければなりません。 – Tom

+0

索引についての説明をお寄せいただきありがとうございます。とてもうれしいですが、あなたの説明は上記の質問に答えられませんでした。 –

+0

あなたは正しいです、私は明示的に最終的な結論を言っていませんでした:私はちょうど4行が3つのバケツに落ちることを示しました。既存のインデックスの3つのバケットの1つに追加される可能性のある別の行を作成できると確信しています。そうすれば、バケットの数は変わらず、インデックスのカーディナリティーは変更されませんでした。申し訳ありません。 – scraimer

8

MySQLがカーディナリティを計算しない理由を私は確信できませんが、私は推測できます。 MySQL manualの状態は次のとおりです。

カーディナリティ:インデックス内の一意の値の見積もり。これは、ANALYZE TABLEまたはmyisamchk -aを実行することによって更新されます。カーディナリティは、整数として格納された統計に基づいてカウントされるため、小さなテーブルでも値は必ずしも正確ではありません。カーディナリティが高いほど、MySQLが結合を実行する際にインデックスを使用する可能性が高くなります。

FULLTEXTインデックスは、強制的にインデックスを使用するMATCH ... AGAINST(...)クエリでのみ使用されます。これらのフィールドにFULLTEXT索引がない場合、MATCH ... AGAINST構文は機能しません。

私の推測では、は実際には不要であるため、カーディナリティは計算されません。

カーディナリティが設定されていなくても、インデックスに対する検索が機能することに注意してください。

レコードの場合、ANALYZE TABLE foobar文は、カーディナリティーを正しく設定しているようです。

関連する問題