为什么一个索引有效而另一个没有?

时间:2013-04-23 13:00:48

标签: mysql

请原谅,如果这是一个非常愚蠢的问题,但我是MySQL新手。我有一个相当大的数据库(70 GB),结构简单(只有一个表),我打算用它来快速检索记录。你可以想象,点击一个70GB的平面文件并不好玩。

在我的第一次尝试中,我创建了一个表(没有任何花哨,1个ENUM,4个无符号INT和2个FLOAT)。由于没有索引的数据检索速度很慢,我在表填充数据之后创建了一个索引,使用类似

的方法
create index myid_index on mytable (myid) using btree;

在这之后,一切正常。检索速度对我来说还可以。然后我注意到我导入数据时出错,所以我重新开始了。这一次,我在实际填充表之前使用索引定义了表。这就是我理解应该做的事情。该命令类似于

create table mytable ( ... , myid INTEGER unsigned, ..., index USING BTREE (myid))

当我这样做时,创建了一个索引,但它似乎不起作用,即检索速度慢。显然没有使用索引。

两个程序的索引具有相同的大小,并且完全相同地显示在“explain mytable”视图中。唯一的区别是,如果在导入了所有数据后定义索引,则索引仅适用于我。

我做错了什么?当我们遇到它时,第二个问题:当我使用'create index'命令定义索引时,我必须给它一个名字。这个名字用的是什么?我不必在查询期间指定它,是吗?

1 个答案:

答案 0 :(得分:3)

tl; dr:由于以下内容没有解决问题,欢迎提供更多答案

实际上,最好先批量导入数据,然后创建索引。通过在导入之前创建索引,您强制MySQL在插入每一行后重新计算索引(这不是完全事实上发生了什么,但它在概念上是接近的)。相反,如果在导入后创建索引,则索引只需构造一次。

由于索引在数据导入期间多次更新,可能会出现碎片,因此性能下降。我建议您在大量插入后发出OPTIMIZE TABLE [the_table]

关于第二个问题,指定索引的名称是可选的。如果省略该子句,MySQL默认创建一个。我建议明确指定它,它使检索更容易(例如,你需要在DROP INDEX语句中指定索引名称。)