我有一张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)
经过10个小时的等待后,我最终放弃了这种方法。
这个问题有可行的解决办法吗?
更新:该表不太可能被更新或插入或删除。之所以在该列上创建索引text
是因为这种sql查询会经常执行:
SELECT page_id FROM text_page WHERE text = ?
更新:我已经通过对表进行分区解决了该问题。
该表按列分为 40 个部分text
。然后在表上创建索引大约需要 1 小时才能完成。
当表很大时,MySQL 索引创建似乎会变得非常慢。分区会将表缩小为较小的主干。
答案1
是不是你的系统不能胜任这项任务?我不使用 MySQL(这里是 SQL Server),但我知道索引一个 8 亿条目表的痛苦。基本上……你需要合适的硬件(例如:大量快速磁盘)。我现在使用了近十几个 Velociraptor,性能非常好 ;)
SQL 服务器(不是 MS SQL Server,而是使用 SQL 的数据库服务器)的存亡取决于磁盘访问,而普通磁盘无法胜任更大规模的操作任务。
答案2
您可能想要在文本字段的前 10 个字符上创建索引(例如,10 个)。
来自文档:
可以创建仅使用列值前导部分的索引,使用 col_name(length) 语法指定索引前缀长度:
CREATE INDEX ix_text ON text_page (text(10))
答案3
我已经通过对表进行分区解决了该问题。
该表按列分为 40 个部分text
。然后在表上创建索引大约需要 1 小时才能完成。
当表很大时,MySQL 索引创建似乎会变得非常慢。分区会将表缩小为较小的主干。
答案4
如果您不需要进行如下查询:
SELECT page_id FROM text_page WHERE text LIKE '?%';
我建议创建一个新的哈希列并按该列对表进行索引。表 + 索引的总体大小可能会小得多。
更新型多巴胺:顺便说一下,14 亿个主键整数占用大约 6 GB,也就是说字符串的平均长度小于 30 个字符,也就是说在前缀上建立索引可能更可取。
你还应该看看合并存储引擎。