当我添加新索引时,为什么MySQL中索引的基数保持不变?

Tom*_*Tom 10 mysql indexing full-text-search cardinality

我在我的一个MySQL数据库表中添加了一个FULLTEXT索引,如下所示:

ALTER TABLE members ADD FULLTEXT(about,fname,lname,job_title);
Run Code Online (Sandbox Code Playgroud)

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

我运行了一个analyze table命令,但似乎没有做任何事情.

analyze table members
Run Code Online (Sandbox Code Playgroud)

索引字段的相应类型是varchar(100),varchar(100),text,varchar(200),使用的引擎是MyISAM,表有大约30,000行,都是唯一的.我的MySQL版本是5.0.45.

难道我做错了什么?

Sha*_*mer 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
Run Code Online (Sandbox Code Playgroud)

那么数据库看的只是4列(a,b,c,d):

a  b  c  d  
-- -- -- --
1  1  1  1 
1  2  1  1 
1  3  1  1 
Run Code Online (Sandbox Code Playgroud)

看到只剩下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
Run Code Online (Sandbox Code Playgroud)

因此,当我们只查看(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
Run Code Online (Sandbox Code Playgroud)

但是我们想通过(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
Run Code Online (Sandbox Code Playgroud)

最后,我们将具有identicle(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
Run Code Online (Sandbox Code Playgroud)

看到了吗?(a,b,c,d)的值(1,1,1,1)(1,2,1,1)和(1,3,1,1)已经成为我们查询表的关键进入原始表的行.

实际上,这些都不会发生,但它应该让你对如何完成索引的"天真"(即直接)实现有一个好主意.

但最重要的是:基数只测量索引中有多少个唯一行.在我们的示例中,查询表中的键数为3.

希望有所帮助!


Veg*_*sen 12

我无法肯定地回答为什么MySQL不计算基数,但我可以猜测.在MySQL手册状态:

基数:索引中唯一值数量的估计值.这是通过运行ANALYZE TABLE或myisamchk -a更新的.基数是根据存储为整数的统计数据计算的,因此即使对于小型表,该值也不一定精确.基数越高,MySQL在进行连接时使用索引的可能性就越大.

FULLTEXT索引仅用于MATCH ... AGAINST(...)查询,这会强制使用索引.如果这些字段上没有FULLTEXT索引,则MATCH ... AGAINST语法不起作用.

我的猜测是基数没有计算,因为它确实没有必要.

请注意,即使未设置基数,对索引的搜索仍然有效.

为了记录,ANALYZE TABLE foobar语句似乎正确地设置了基数.