Mysql 高效地重新索引大型数据库(英文维基百科)

Mysql 高效地重新索引大型数据库(英文维基百科),mysql,sql,database,xampp,mediawiki,Mysql,Sql,Database,Xampp,Mediawiki,要点 在对英文维基百科执行40+GB的大规模导入之前,我必须临时删除三个表(“页面”、“修订版”和“文本”)中的索引和自动增量字段以处理负载。现在,我终于成功地将英文维基百科导入到我的本地机器,并创建了一个本地镜像(MediaWiki API)。耶 但是,我现在需要在不到十年的时间内重新创建索引和自动增量字段。幸运的是,(1)在删除索引和字段之前,我在phpmyadmin中拍摄了大量相关表的屏幕截图;(2) 我可以极其精确地解释我在进口前采取的步骤;(3)对于任何精通MySQL的人来说,这应该不

要点

在对英文维基百科执行40+GB的大规模导入之前,我必须临时删除三个表(“页面”、“修订版”和“文本”)中的索引和自动增量字段以处理负载。现在,我终于成功地将英文维基百科导入到我的本地机器,并创建了一个本地镜像(MediaWiki API)。耶

但是,我现在需要在不到十年的时间内重新创建索引和自动增量字段。幸运的是,(1)在删除索引和字段之前,我在phpmyadmin中拍摄了大量相关表的屏幕截图;(2) 我可以极其精确地解释我在进口前采取的步骤;(3)对于任何精通MySQL的人来说,这应该不会太难。不幸的是,我在MySQL方面没有任何专业知识,所以“小步骤”的解释将非常有用

正是我所做的(准备导入):

步骤1、2、3:此图显示了在我通过单击“更改”并取消选中“自动增量”(准备导入)修改字段页面id之前的表格页面。我对表修订版中的修订id字段和表文本中的旧id字段执行了完全相同的修改,但省略了屏幕截图以避免冗余

步骤4:此图描述了在我删除所有索引之前,表页面的索引

步骤5:这幅图描述了在我删除所有索引之前,表修订版的索引

步骤6:此图描述了在我删除所有索引之前,表文本的索引

我现在需要什么(导入后恢复):

我只需要恢复原始索引和自动增量字段,而不需要等待100年


设置细节:PHP5.3.8(apache2handler)、MySQL 5.5.16(InnoDB)、Apache2.2.21、Ubuntu12.04 LTS、MediaWiki 1.19.0(私有wiki)

我非常喜欢Wikipedia,所以我会尽力提供帮助

你需要使用大量的

ALTER TABLE
添加主键

ALTER TABLE page ADD PRIMARY KEY (page_id);
ALTER TABLE revision ADD PRIMARY KEY (rev_id);
ALTER TABLE text ADD PRIMARY KEY (old_id);
重新添加自动增量

ALTER TABLE page MODIFY COLUMN page_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT;
在继续之前,我需要所有表的表说明。如果版本id和旧版本id与页面id的定义相同,则:

ALTER TABLE revision MODIFY COLUMN rev_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE text MODIFY COLUMN old_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT;
添加唯一键

ALTER TABLE page ADD UNIQUE name_title(page_namespace, page_title);
ALTER TABLE revision ADD UNIQUE rev_page_id(rev_page, rev_id);
其他指标

ALTER TABLE page ADD INDEX page_random(page_random);
ALTER TABLE page ADD INDEX page_len(page_len);
ALTER TABLE page ADD INDEX page_redirect_namespace(page_is_redirect, page_namespace, page_len);
ALTER TABLE revision ADD INDEX rev_timestamp(rev_timestamp);
ALTER TABLE revision ADD INDEX page_timestamp(rev_page, rev_timestamp);
ALTER TABLE revision ADD INDEX user_timestamp(rev_user, rev_timestamp);
ALTER TABLE revision ADD INDEX user_text_timestamp(rev_user_text, rev_timestamp);

同样,可能有一些列定义改变了这些内容。您需要提供创建表的信息。

+1对于一个写得很好的问题,但对于这种大小的数据集,无论您如何创建索引,恐怕都需要一段时间。如果这是MyISAM,您可以避免在导入之前删除索引:在MyISAM表中,您可以在完成数据导入后禁用它们并再次启用它们,在这种情况下,MySQL将通过排序自动修复索引。但即便如此,即使在快速系统上,对40gb数据进行排序也需要一段时间。你使用的是InnoDB,这是不可能的。我不认为禁用和启用比创建一个新索引更快。从零开始,对数据进行排序并编写索引。记住,我是一名MySQL新手。我知道我做了什么,但不知道如何排序、重新索引等。因此,如果您用代码进行解释,将非常有帮助。如果禁用和启用MyISAM可以大大加快重新编制索引的速度,我总是可以从头开始重新构建所有内容——我已经做了很多次了,我可以在大约5小时内轻松地再做一次。关键是我对MySQL几乎一无所知,所以如果可能,请具体说明并提供代码示例。也许您可以在索引构建期间关闭MySQL的耐久性和事务日志记录。好吧,这是可能的。在任何情况下,你都必须创建索引,而且没有魔法开关可以让你这么快就完成。这就是你的意思吗?这是修订表,文本表在顶部可见。如果没有,我应该在哪里查看?“我还有很多其他的屏幕截图。”BrianSchmitz Yup做了一些修改,现在一切都正常了。以后,请使用“SHOW CREATE TABLE_name”而不是phpmyadmin的屏幕截图。@BrianSchmitz确保按照我列出的顺序运行每个命令,并将索引留到最后。我不知道要花多长时间,因为我不知道你有多少行。这可能会给你更多的线索@BrianSchmitz它与我的代码做的事情相同,只是它将命令组合在一起。在速度方面应该是相同的数量级。删除索引是相同的。你还没有完成重新编制索引吗?@BrianSchmitz你完全正确。您试图将一个唯一键定义为page:namespace和page_title的组合,但您有两行,其中page_namespace为0,page_title为main_page。放下一个,你会没事的