我在小型MyISAM表上工作 - 大约30k条目,大小 - 10mb。其中一个字段是varchar(500+),因为我使用utf8_unicode_ci我无法索引此字段(我达到1000字节限制),同时我需要根据此字段执行大量“get_or_create”查询。我正在尝试优化数据库,但事情仍然很慢。
创建附加字段是否是一个很好的解决方案,它将保存varchar值的md5并将其索引/用于查找?有人试过这种方法吗?
答案 0 :(得分:1)
对我来说,使用这么宽的列作为键是一个坏主意,但除此之外你绝对可以做出类似你的建议。您甚至不需要使用MD5,您只需要一个产生很少冲突的哈希函数,但不需要唯一性。 CRC32
产生的值很小,而且非常快。
说你的表看起来像这样:
CREATE TABLE data (lots_of_text VARCHAR(500));
将其更改为:
CREATE TABLE data (text_hash INT, lots_of_text VARCHAR(500), INDEX (text_hash));
当你插入行时,你会这样做:
INSERT INTO data (lots_of_text, text_hash)
VALUES ("lots and lots of text", CRC32("lots and lots of text"));
然后你可以检索这样的行:
SELECT lots_of_text FROM data
WHERE text_hash = CRC32("lots and lots of text")
AND lots_of_text = "lots and lots of text";
查询将使用text_hash
上的索引,但由于CRC32
不会生成唯一值,您仍需要检查lots_of_text
字段是否相等 - 但查询仍然是快,因为最多几行将具有相同的哈希值。
这种方法的一个变体是使用前50个字符作为哈希值,前50个字符相同的行数很可能很低。