【问题标题】:Re-indexing huge database (the English Wikipedia) efficiently有效地重新索引庞大的数据库(英文维基百科)
【发布时间】:2012-06-10 22:46:58
【问题描述】:

要点

在对英语 Wikipedia 执行 40+ GB 的大规模导入之前,我不得不暂时从三个表(“page”、“revision”和“text”)中删除索引和自动增量字段以处理负载。现在我终于成功地将英文维基百科导入到我的本地机器并创建了一个本地镜像(MediaWiki API)。耶!

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

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

第 1、2、3 步:这张图片描绘了在我通过点击“更改”并取消选中“自动增量”来修改字段 page_id 之前的表格 页面 (准备进口)。我对表 revision 中的字段 rev_id 和表 text 中的 old_id 执行完全相同的修改,但省略了屏幕- 镜头以避免冗余。

第 4 步:这张图片描述了在我删除所有索引之前,page 表的索引。

第 5 步:这张图片描述了我删除所有表之前 revision 的索引。

第 6 步:这张图片描述了我删除所有表 text 之前的索引。

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

我只需要恢复原始索引和自增字段,无需等待一百年。

设置详情:PHP 5.3.8 (apache2handler)、MySQL 5.5.16 (InnoDB)、Apache 2.2.21、Ubuntu 12.04 LTS、MediaWiki 1.19.0(私人 wiki)

【问题讨论】:

  • +1 是一个写得很好的问题,但恐怕对于这种大小的数据集,无论你怎么做,创建索引都需要一段时间。如果这是 MyISAM,您可以避免在导入之前删除索引:在 MyISAM 表中,您可以禁用它们并在完成导入数据后再次启用它们,在这种情况下 MySQL 将通过排序自动修复索引。但即便如此,即使在快速系统上,对 40gb 数据进行排序也需要一段时间。而且您正在使用 InnoDB,这在 AFAIK 中是不可能的。
  • 我不认为禁用和启用比仅仅建立一个新索引更快。您从零开始,对数据进行排序并写入索引。
  • 记住我是一个完整的 MySQL 新手。我知道我做了什么,但不知道如何排序、重新索引等,所以如果你用代码解释会非常有帮助。如果事实证明禁用和启用使用 MyISAM 可以大大加快重新索引的速度,我总是可以从头开始重建所有内容——我已经完成了很多次,我可以在大约 5 小时内轻松地再次完成。关键是我对MySQL几乎一无所知,所以请具体点,如果可能的话提供代码示例。
  • 也许您可以在索引构建期间关闭 MySQL 的持久性和事务日志记录。 AFAIK 这是可能的。在任何情况下,您都必须创建索引,而且没有什么神奇的开关可以快速完成。

标签: mysql sql database xampp mediawiki


【解决方案1】:

我真的很喜欢维基百科,所以我会尽力提供帮助。

你需要大量使用

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;

在继续之前,我需要所有表格的表格描述。如果 rev_id 和 old_id 与 page_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);

同样,可能有列定义会改变这些内容。您需要提供 CREATE TABLE 信息。

【讨论】:

  • 这是你的意思吗?这是修订表imageshack.us/photo/my-images/38/revid.png,文本表在imageshack.us/photo/my-images/59/textindex.png 的顶部可见如果没有,我应该在哪里查看?我还有很多其他的屏幕截图。
  • @BrianSchmitz 是的,做了一些更改,现在一切正常。以后使用“SHOW CREATE TABLE table_name”代替phpmyadmin的截图。
  • @BrianSchmitz 确保按照我列出的顺序运行每个命令,并将索引留到最后。我不知道需要多长时间,因为我不知道你有多少行。这可能会给你更多的线索。 stackoverflow.com/questions/2483205/…
  • @BrianSchmitz 它与我的代码做同样的事情,只是它将命令组合在一起。在速度方面应该是同一个数量级。下降的索引是相同的。您还没有完成重新索引吗?
  • @BrianSchmitz 你说得对。您正在尝试将唯一键定义为 page:namespace 和 page_title 的组合,但您有 2 行 page_namespace 为 0 且 page_title 为 main_page。放下一个,你应该没事
猜你喜欢
  • 1970-01-01
  • 2011-12-13
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多