Mysql

MySQL CREATE INDEX 變慢

  • November 30, 2020

我的分析表有 190M 行,大約 150GB 大小。儲存引擎是 MyISAM

key-buffer-size=16G
myisam_sort_buffer_size=2G
myisam-max-sort-file-size=200G.

機器有32GB記憶體。在創建 10 個簡單索引(沒有覆蓋,沒有前綴,只是使用 BTREE 的列名)時,我注意到:

  • 第一個索引 - 40 分鐘
  • 第二個索引 - 50 分鐘
  • 第五指數 - 2 小時
  • 第十一指數 - 3 1/2 小時

每個索引在 .myi 文件中增加 1GB 到 3GB。有沒有人經歷過類似的執行時間增加?有沒有辦法獲得其他索引的第一個索引創建的性能?

你的 DDL 一定是在做一些奇怪的事情,或者你有一個非常非常舊的 MySQL 版本。

MyISAM 索引的創建可能非常昏昏欲睡。差不多十年前我寫過這個。

如果沒有您提供任何其他詳細資訊,我只能猜測。它是這樣的:

我懷疑你一定只是在做以下事情:

ALTER TABLE mytable ADD INDEX (column01);
ALTER TABLE mytable ADD INDEX (column02);
ALTER TABLE mytable ADD INDEX (column03);
...
ALTER TABLE mytable ADD INDEX (column10);
ALTER TABLE mytable ADD INDEX (column11);

我想提出以下建議

SUGGESTION #1:同時建構所有 11 個索引

您應該在單個 DDL 語句中創建所有 11 個索引

ALTER TABLE myisamtable
   ADD INDEX (column01),
   ADD INDEX (column02),
   ADD INDEX (column03),
   ...
   ADD INDEX (column10),
   ADD INDEX (column11)
;

建議 #2:延遲索引建構

您可以禁用非唯一索引的建構,以便排序並完成。

這樣做可以為每個索引製作更小的 BTREE

ALTER TABLE mytable DISABLE KEYS;
... 
ALTER TABLE mytable ENABLE KEYS;

建議#3:使用臨時表

如果您想手動測試,您可以創建一個臨時表,將所有索引添加到空臨時表,禁用索引,插入數據,啟用索引和切換錶名。

這是我剛剛向您描述的範例

CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable_new
   ADD INDEX (column01),
   ADD INDEX (column02),
   ADD INDEX (column03),
   ...
   ADD INDEX (column10),
   ADD INDEX (column11)
;
ALTER TABLE mytable_new DISABLE KEYS;
INSERT INTO mytable_new SELECT * FROM mytable;
ALTER TABLE mytable_new ENABLE KEYS;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
DROP TABLE mytable_old;

試一試 !!!

羅蘭多,非常感謝您的解釋。我在這個磨難期間(46 小時,今天早上完成)跟踪了磁碟大小和文件訪問,是的.. 即使在 MySql 5.6 中也會發生這種情況。我的陳述是:

CREATE INDEX idx1 ....;
CREATE INDEX idx2 ....;
CREATE INDEX idx3 ....;
...

我在“顯示程序列表”中看到了所有數據是如何首先複製到臨時表然後編制索引的。將使用

ALTER TABLE ADD INDEX, ADD INDEX, ADD INDEX ...

將來。

謝謝!問題解決了..問題回答了!

引用自:https://dba.stackexchange.com/questions/141192