10

次のように、MySQL データベース テーブルの 1 つに FULLTEXT インデックスを追加しました。

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

問題は、phpmyadminを使用すると、新しいインデックスのカーディナリティが1しかないことがわかります。これは、インデックスが使用されないことを意味しますか?

analyze table コマンドを実行しましたが、何もしていないようです。

analyze table members

インデックス フィールドのそれぞれのタイプは varchar(100)、varchar(100)、text、varchar(200) で、使用されるエンジンは MyISAM で、テーブルには約 30,000 行あり、すべてが一意です。私の MySQL バージョンは 5.0.45 です。

私は何か間違ったことをしていますか?

4

2 に答える 2

14

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

インデックスをバケットに基づくルックアップ テーブル (ハッシュなど) と考える場合、カーディナリティはバケットの数です。

仕組みは次のとおりです。一連の列に対してインデックスを作成すると(a,b,c,d)、データベースはテーブル内のすべての行を調べ、各行について、それらの 4 つの列の順序付けられた 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、または行識別子もあります。したがって、元のテーブルは次のようになります。

(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

したがって、(a、b、c、d) の 4 つの列だけを見ると、実際には行 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

しかし、行 ID ではなく (a,b,c,d) で検索したいので、次のようなものを生成します。

(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

最後に、同一の (a、b、c、d) 値を持つ行のすべての行 ID をグループ化します。

(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 でした。

それが役立つことを願っています!

于 2009-04-16T10:53:36.040 に答える
12

MySQL がカーディナリティを計算しない理由を明確に答えることはできませんが、推測はできます。MySQL のマニュアルには次のように記載されています。

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

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

私の推測では、カーディナリティは実際には必要ないため計算されていません

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

記録として、ANALYZE TABLE foobar ステートメントはカーディナリティを正しく設定しているようです。

于 2009-04-16T11:30:41.397 に答える