10

我已将 FULLTEXT 索引添加到我的 MySQL 数据库表之一,如下所示:

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

问题是使用phpmyadmin我可以看到我的新索引的基数只有1。这是否意味着永远不会使用索引?

我已经运行了一个分析表命令,但它似乎没有做任何事情。

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 列的有序四组。假设您的表格如下所示:

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

但是我们想通过 (a,b,c,d) 而不是 row 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

最后,我们将具有相同 (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

看到了吗?(a,b,c,d) 的值,即 (1,1,1,1) (1,2,1,1) 和 (1,3,1,1) 已成为我们查找表的键到原始表的行中。

实际上,这一切都没有真正发生,但它应该让您对如何完成索引的“幼稚”(即直接)实现有一个很好的了解。

但底线是:基数只是衡量索引中有多少唯一行。在我们的示例中,这是我们查找表中的键数,即 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 回答