Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL-创建索引需要多长时间?_Mysql_Indexing - Fatal编程技术网

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

MySQL-创建索引需要多长时间?,mysql,indexing,Mysql,Indexing,谁能告诉我在MySQL中添加一个键是如何伸缩的?我在数据库中有500000000行,trans,其中有I(INT UNSIGNED)、j(INT UNSIGNED)、nu(DOUBLE)、a(DOUBLE)列。 我尝试为一列建立索引,例如 ALTER TABLE trans ADD KEY idx_A (A); 我等着。对于一个14000000行的表,在我的MacBook Pro上执行大约需要2分钟,但对于整个5亿行,需要15个小时的时间。是我做错了什么,还是我只是对数据库索引如何随行数扩展感

谁能告诉我在MySQL中添加一个键是如何伸缩的?我在数据库中有500000000行,trans,其中有I(INT UNSIGNED)、j(INT UNSIGNED)、nu(DOUBLE)、a(DOUBLE)列。 我尝试为一列建立索引,例如

ALTER TABLE trans ADD KEY idx_A (A);

我等着。对于一个14000000行的表,在我的MacBook Pro上执行大约需要2分钟,但对于整个5亿行,需要15个小时的时间。是我做错了什么,还是我只是对数据库索引如何随行数扩展感到幼稚?

根据我的经验:如果硬件能够应对,那么使用MySQL索引大型表通常会线性扩展。到目前为止,我已经在大约100000000行的表上尝试过了,但没有在笔记本上尝试过——主要是在强大的服务器上

我想这主要取决于硬件因素、您正在使用的表引擎类型(MyIsam、INNO或其他)以及表是否在两者之间使用。当我这样做的时候,通常磁盘的使用率跳得很高,不像CPU的使用率。不确定MacBook的硬盘,但我想它们不是最快的


如果您使用的是MyISAM表,请仔细查看表目录中的索引文件,看看它是如何随时间变化的。

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

CREATE TABLE x ( 
  i INTEGER UNSIGNED NOT NULL, 
  j INTEGER UNSIGNED NOT NULL, 
  nu DOUBLE NOT NULL, 
  A DOUBLE NOT NULL 
);
至于创建索引所需的时间,这需要表扫描,并将显示为
REPAIR BY SORTING
。在您的情况下(即海量数据集),创建具有所需索引的新表并将数据插入其中应该会更快,因为这将避免通过排序进行
修复,因为索引是按顺序构建在insert上的。中解释了一个类似的概念

然后将插入脚本编写成块(根据文章),或使用
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
mysqldump originalDB trans--extended insert--skip add drop table--no create db--no create info>originalDB.trans.sql
mysql trans_clone

这将插入数据,但不需要重新生成索引(索引是在插入每一行时生成的),并且应该完成得更快

有几个因素需要考虑:

  • 排序是一个N.log(N)操作
  • 1400万行的排序可能很适合主内存;有5亿行的排序可能没有,因此排序溢出到磁盘,这大大减慢了速度

由于该系数约为30,大数据集的标称排序时间约为50倍——不到两小时。然而,每个数据值需要8个字节,另外还需要8个字节的开销(如果您更了解mySQL在索引中存储的内容,那么这是对mySQL的猜测)。那么,14M×16≈ 220 MB主存储器。但500M×16≈ 8GB主存储器。除非你的机器有那么多的空闲内存(MySQL被配置为使用它),否则大的排序会溢出到磁盘上,这会占用很多剩余的时间。

因此,从理论上讲,如果排序步骤是一个N.log(N)操作,那么对大表进行分区将节省操作时间

在100个相等的文件中划分50万行的表可以获得约30%的收益:因为 50000000*log(50000000)=4349 485 002 及
100*(5000000/100*LOG(5000000/100))=3349 485 002

感谢您的快速回复,比约恩。我听从了你的建议。我认为文件#sql-a8_6.MYD(当前7455506432字节)和#sql-a8_6.MYI(当前2148865024字节)分别是正在构建的数据库的新版本和我请求的索引?那么,如果原始表是trans.MYD(12645156375字节),我大约完成了60%了?看起来我最好把这张大桌子分成20张左右的小桌子。谢谢你,克里斯蒂安,好了。好吧,这一切都取决于你想用那么多的数据做什么。500.000.000行太多了,因此如果您想在之后做一些奇特的报告,请尝试最小化数据。要么尝试拆分它,要么在MySQLs分区功能(从5.1版开始)上抢购。非常感谢,这对我来说很有意义-我只有4GB。看起来像是拆分(分区?)上面建议的数据很有意义。您拆分了表吗?这花了多长时间?您可能需要研究拆分(数据库分片)您的表注意,与其执行
mysqldump
和还原(在整个过程中至少需要一个连续的表读取锁),不如执行以下操作:,您可以使用Percona工具包,它可以在多个过程中创建和复制数据,从而消除连续锁定要求。
mysqldump originalDB trans  --extended-insert --skip-add-drop-table --no-create-db --no-create-info > originalDB .trans.sql
mysql trans_clone < originalDB .trans.sql