MySQL:在14亿条记录上创建索引


9

我有一张有14亿条记录的表。表结构如下:

CREATE TABLE text_page (
    text VARCHAR(255),
    page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii

要求是在列上创建索引text

该表的大小约为34G。

我试图通过以下语句创建索引:

ALTER TABLE text_page ADD KEY ix_text (text)

经过十个小时的等待,我终于放弃了这种方法。

有什么可行的解决方案吗?

UPDATE:该表不太可能被更新,插入或删除。之所以要在该列上创建索引,text是因为这种SQL查询将经常执行:

SELECT page_id FROM text_page WHERE text = ?

更新:我已经通过分区表解决了这个问题。

桌子被分成40列text。然后在表上创建索引大约需要1个小时。

当表大小很大时,MySQL索引的创建似乎变得很慢。分区将表缩小为较小的主干。


1
使用普通CREATE INDEX语句有什么问题?

我建议在ServerFault上解决这个问题可能会更好-它更多是数据库管理员而不是编程问题。
从这里开始

@Derk:正常的CREATE INDEX方法太慢。我必须在1天内完成任务。

1
嗯...我认为您无法解决这个问题。建立索引需要DBMS扫描所有记录,收集它们的“文本”字段并插入/更改相应的树节点/子树。这对于34G来说需要花费很多时间...
chiccodoro 2010年

您的数据库服务器有多少内存?您是否已配置MySQL以使用所有这些内存,还是限制了它自身?

Answers:


4

难道是您的系统无法完成任务吗?我不使用MySQL(这里是SQL Server),但是我知道索引8亿个条目表的痛苦。基本上....您需要适当的硬件(例如:大量快速光盘)。我现在使用了将近十二个Velociraptor,性能非常好;)

SQL Server(不是作为MS SQL Server,而是作为使用SQL的数据库服务器)会随着磁盘访问而生死,而普通磁盘仅不能满足较大操作的任务。


我的疑问是,如果记录数很少,索引创建通常会非常快;说,数百万。但是,当计数达到数十亿时,索引创建就会变得如此缓慢。似乎时间增长是指数级的。

应该不是真的。MySQL通常有限制,但它不是废话数据库,那将是非常糟糕的。索引的生成速度会变慢,但是通过log(n)而不是(n)进行,因此它实际上并不是那么糟糕。
TomTom

4

您可能想在文本字段的第一个(例如10个)字符上创建索引。

从文档中:

可以使用col_name(length)语法指定仅使用列值的开头部分的索引来创建索引前缀长度:

CREATE INDEX ix_text ON text_page (text(10))

4

我已经通过分区表解决了这个问题。

桌子被分成40列text。然后在表上创建索引大约需要1个小时。

当表大小很大时,MySQL索引的创建似乎变得很慢。分区将表缩小为较小的主干。


那么40 x 1小时少于10小时?
symcbean 2015年

3

将sort_buffer_size设置为4GB(或多少,取决于您有多少内存)。

现在,create index正在执行排序,但是由于您具有32MB的sort_buffer_size,因此基本上不需要了硬盘。


这些帖子几乎直接与您不同意:xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size和更好的 ronaldbradford.com/blog/… 听起来这不是全球性的价值,而是每个查询,因此建议您每个查询4GB。另外,当它超过256K时,它会被映射到磁盘,而不是实际的内存中。如果将其减小,则需要多次通过,但可以避免使用磁盘(不交换)。
Ry4an Brase 2010年

3

如果您不需要进行以下查询:

SELECT page_id FROM text_page WHERE text LIKE '?%';

我建议创建一个新的哈希列,并按该列对表进行索引。表+索引的总大小可能会小得多。

UPD:顺便说一句,14亿个主键整数约占6 GB,即字符串的平均长度小于30个字符,即在前缀上进行索引可能更可取。

您还应该看看MERGE存储引擎。


2

一种方法是用索引集创建一个新表,然后将数据复制到新表中。

另外,请确保您有足够的临时空间。


1
我已经尝试过这种方法。10小时后,不到1%的数据已复制到新表中。

1
杜德...这是14亿条记录。不是十亿,十亿。好多啊。无论如何,要花一点时间。

如果选择这样做,则将副本分成较小的块。每个副本说100到2亿个。

1
@decompiled,将其拆分为较小的块不会做任何事情(实际上,它可能会使效率降低)。@Bryan,即使有14亿条记录,也不需要花费1000个小时。

0

如果您仍然想知道如何做到最好,我建议您使用在线更改表工具。

互联网上有很多它们,其中著名的是:

大表(超过5亿条记录)也存在相同的问题,而且更改非常完美。它创建一个新的tmp表,在原始表上添加触发器(用于新的更新/删除/插入记录),同时将所有记录复制到新表中(具有新结构)

祝好运!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.