2009-04-16 23 views
8

我添加了一個FULLTEXT索引到我的MySQL數據庫的一個表如下:爲什麼添加新索引時,MySQL中索引的基數保持不變?

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

的問題是,使用的phpmyadmin我可以看到我的新指數的基數是唯一。這是否意味着索引永遠不會被使用?

我已經運行了分析表命令,但它似乎沒有做任何事情。

analyze table members 

的相應類型的索引字段是VARCHAR(100),VARCHAR(100),文本,VARCHAR(200)和所使用的發動機MyISAM和該表具有約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個唯一還剩下幾行?那些將成爲我們的桶,但我們會回到那個。實際上,表格中的每一行也都有記錄標識或行標識符。所以,我們原來的表看起來像這樣:

(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 

所以,當我們在看只有的4列(A,B,C,d),我們真的還看行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

感謝您的索引信息。很好解釋。我的索引的基數應該超過1,因爲有30000行,幾乎每個成員都有不同的名字? – Tom 2009-04-16 11:24:17

8

我不能肯定地回答爲什麼MySQL不計算基數,但我可以猜測。 MySQL manual指出:

基數:索引中唯一值數量的估計值。這通過運行ANALYZE TABLE或myisamchk -a進行更新。基數是基於統計數據存儲爲整數,所以即使對於小型表格,該值也不一定準確。基數越高,MySQL在進行連接時使用索引的機會就越大。

FULLTEXT索引僅用於MATCH ... AGAINST(...)查詢,這會強制索引被使用。如果在這些字段上沒有FULLTEXT索引,則MATCH ... AGAINST語法不起作用。

我的猜測是基數不計算,因爲它確實沒有必要

請注意,即使未設置基數,也會對索引進行搜索。

爲了記錄,ANALYZE TABLE foobar語句似乎正確地設置了基數。