2010-10-03 35 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