2009-04-16 24 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语句似乎正确地设置了基数。