2010-10-03 41 views
3

我在一个拥有3500万条记录的表上创建了一个新的索引,它现在已经运行了近1天。以前,当我创建索引需要20分钟时,那里的列是浮动的。新idnex是一个varchar(45)确定mysql中索引的状态

我用processlist的命令,它显示了索引创建仍与下面的输出

65417 | Repair with keycache | CREATE INDEX insert_index on checkins(dateinserted) 

我想知道的进展,如果任何人都可以给我建议在寻找如果查询实际上已经死了,并且只是坐在流程列表中。也许在某个阶段出了问题,我不知道。

谢谢

回答

6

您的索引正在建设中,但速度很慢。

MySQL有可用于生成索引两种方法:

  1. 通过排序。这是最快的方法,但占用大量内存。
  2. by keycache。缓慢,缓慢,缓慢 - 但消耗少量记忆。

keycache方法有点像插入排序:值一次插入索引之一。当INSERT语句用于向表中添加行时,这与服务器使用的方法相同。

排序方法使用快速排序对所有值进行排序,然后从中建立索引。它速度非常快,但需要大量内存和临时磁盘空间。

某些服务器变量可以增加可用于排序方法的空间,因此允许它使用较大的表。见myisam_max_sort_file_size

http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_myisam_max_sort_file_size

在Linux上,你可以通过检查用于建立索引的临时文件的大小,追踪指标修复的进度。以下命令将列出了由MySQL进程保持打开的所有文件:

sudo ls -l /proc/[mysql-pid]/fd 

然后以他们的名义哈希检查出来的人的规模 - 这些都是临时文件。

+0

如果我再次插入数据,一切都会中断吗? – Steve 2010-10-03 16:52:00

+0

如果索引构建仍在运行,MySQL将不允许您向该表中插入更多数据。 – Martin 2010-10-03 17:18:59

+0

此外,我试图看看临时文件是否正在扩展,但我不知道盒子上的sudo。任何想法的另一种方法?我担心这个过程会以某种方式崩溃,而我只是在同时空转。 – Steve 2010-10-03 17:28:19

2

请记住索引大小至少为35M * 45。如果它是一个utf8列,那么它将是35M * 45 * 3。这是超过4场演出!如果你没有大量的内存来支持它将不得不做大量的磁盘访问,并真的杀死性能。

你能把这个列标准化到另一个表吗?

如果不是这样的话,那么在前8个字符中,这些值往往会有很大的差异?那么你可能只需索引第一个8即可。

+0

这是我根本没有考虑到的事情,因为我没有正确地设计它:)事实上,数据可以很容易地在另一个表格中归一化为更短的值。 – Steve 2010-10-03 22:20:44