MySQL - 创建索引需要多长时间?

xnx*_*xnx 40 mysql indexing

谁能告诉我如何在MySQL中添加关键尺度?我在数据库中有500,000,000行,trans,列i(INT UNSIGNED),j(INT UNSIGNED),nu(DOUBLE),A(DOUBLE).我尝试索引一个列,例如

ALTER TABLE trans ADD KEY idx_A (A);
Run Code Online (Sandbox Code Playgroud)

我等 对于一张14,000,000行的表格,在我的MacBook Pro上执行大约需要2分钟,但对于整个5亿,它需要花费15个小时计算.我做错了什么,或者我只是天真地对数据库的索引如何与行数进行扩展?

Jon*_*ler 38

有几个因素需要考虑:

  • 排序是N.log(N)操作.
  • 14M行的排序很可能适合主内存; 500M行的排序可能没有,因此排序溢出到磁盘,这会大大减慢速度.

由于该因子大小约为30,因此大数据集的标称排序时间将是两倍小时的50倍.但是,每个数据值需要8个字节,另外还需要8个字节的开销(这是猜测 - 如果您对索引中存储的内容有更多了解,请调整到mySQL).所以,14M×16≈220MB主存.但500M×16≈8GB主存.除非您的计算机有足够的内存(并且MySQL已配置为使用它),否则大部分内容将溢出到磁盘,其余时间占很多.


And*_*ndy 6

首先,您的表定义可能会在这里产生很大的不同.如果NULL列中不需要值,请定义它们NOT NULL.这将节省索引中的空间,并且可能是创建它时的时间.

CREATE TABLE x ( 
  i INTEGER UNSIGNED NOT NULL, 
  j INTEGER UNSIGNED NOT NULL, 
  nu DOUBLE NOT NULL, 
  A DOUBLE NOT NULL 
);
Run Code Online (Sandbox Code Playgroud)

至于创建索引所需的时间,这需要一个表扫描并显示为REPAIR BY SORTING.在您的情况下(即海量数据集)应该更快地创建具有所需索引的新表并将数据插入其中,因为这将避免REPAIR BY SORTING操作,因为索引是在插入上按顺序构建的.本文中解释了类似的概念.

CREATE DATABASE trans_clone;
CREATE TABLE trans_clone.trans LIKE originalDB.trans;
ALTER TABLE trans_clone.trans ADD KEY idx_A (A);
Run Code Online (Sandbox Code Playgroud)

然后将插入脚本编入块(根据文章),或使用MYSQLDUMP以下方法转储数据:

mysqldump originalDB trans  --extended-insert --skip-add-drop-table --no-create-db --no-create-info > originalDB .trans.sql
mysql trans_clone < originalDB .trans.sql
Run Code Online (Sandbox Code Playgroud)

这将插入数据,但不需要索引重建(索引是在插入每行时构建的),并且应该更快地完成.

  • 请注意,您可以使用[pt-online-schema-change](http://www.percona.com),而不是进行“ mysqldump”和还原,而在整个过程中至少需要一个连续的表读取锁。 com / doc / percona-toolkit / 2.2 / pt-online-schema-change.html)-它会负责多次创建和复制数据,从而消除了连续锁定的要求。 (2认同)