【问题标题】:Optimizing php/mysql translation lookup with huge database and hash indexes使用庞大的数据库和哈希索引优化 php/mysql 翻译查找
【发布时间】:2013-04-05 08:13:48
【问题描述】:

我目前正在使用 utf8 mysql 数据库。它检查翻译是否已经在数据库中,如果没有,它会进行翻译并将其存储在数据库中。

SELECT * FROM `translations` WHERE `input_text`=? AND `input_lang`=? AND `output_lang`=?;

(另一个字段是“output_text”。)对于基本数据库,它首先会逐字母比较输入文本与“input_text”“TEXT”字段。只要字符匹配,它就会继续比较它们。如果他们停止匹配,它将进入下一行。

我不知道数据库在低级别是如何工作的,但我假设对于基本数据库,它会在确定输入文本不在数据库中之前从数据库的每一行中搜索至少一个字符数据库。

理想情况下,输入文本将被转换为哈希码(例如使用 sha1),并且每个“input_text”也将是一个哈希。然后,如果数据库被正确排序,它可以快速找到与哈希匹配的所有行,然后检查实际文本。如果没有匹配的哈希,那么即使没有手动检查每一行,它也不会返回任何结果。

是否有一种 mysql 存储引擎可以做这样的事情,或者是否有一些额外的 php 可以优化事情?应该将“input_text”设置为某种“索引”吗? (主要/唯一/索引/全文)

有没有另一种兼容php的数据库比mysql好很多?

编辑: 这里讨论的是 MySQL 的 B-Tree vs Hash 索引:

http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html

哈希索引的任何限制对我来说都不是问题。它还说

它们仅用于使用 = 或 运算符的相等比较(但 非常 快)

[“非常”被他们用斜体表示]

新问题:

如何将“input_text”TEXT 设置为哈希索引?顺便说一句,多行包含相同的“input_text”...对于哈希索引可以吗?

http://dev.mysql.com/doc/refman/5.5/en/column-indexes.html

说“MEMORY 存储引擎默认使用 HASH 索引”——这是否意味着我必须更改存储引擎并将列索引设置为 INDEX?

【问题讨论】:

  • 你可能对这个stackoverflow.com/questions/9820801/…感兴趣
  • 顺便说一句,我正在使用 phpMyAdmin。另外,我不是在句子中搜索单个单词。我正在搜索输入字符串是否与数据库中的字符串完全匹配。 (如果匹配,则检查匹配的输入和输出语言)
  • 您是否考虑在末尾添加LIMIT 1?我发现这有助于我自己的使用,因为当整个目标是获得单个匹配时,它会加快查询速度。

标签: mysql hash translation


【解决方案1】:

一个普通的INDEX 子句就足够了(确保索引所有字段,它在磁盘上会很大,但速度更快)。当您使用 LIKE 子句时,FULLTEXT 索引很好;-)

无论如何,对于这种查找,您应该使用像 Redis 这样的 NoSQL 存储,它速度极快,具有内存存储,还可以通过快照进行数据持久化。

这里有一个php的扩展名:https://github.com/nicolasff/phpredis

您将拥有以下形式的 redis 键:YOUR_PROJECT:INPUT_LANG:WORD:OUTPUT_LANG 为了更好地管理数据,只需将每个值替换为您的值即可;)

【讨论】:

    【解决方案2】:

    索引会大大加快查找速度。

    默认情况下,InnoDB 和 MyISAM 中的索引使用搜索树(B-trees)。索引行的长度是有限制的,因此您只需要索引第一个 ~700 字节的文本。

    CREATE INDEX txt_lookup ON translations (input_lang, output_lang, input_text(255));

    这将在input_langoutput_langinput_text 的第一个 255 个字符上创建一个索引。

    当您使用示例查询进行选择时,MySQL 将使用索引快速查找具有适当语言和相同起始 255 个字符的行,然后将慢速字符串与小集合上的列的全长进行比较它从索引中获得的行数。

    【讨论】:

    • 我可能会误解,但您的意思是“input_text”仍然是没有大小限制的 TEXT?
    • 它会有一个大小限制(每个数据类型都有一个),但它可以更高(4GB 或其他东西......)。该索引仅使用字段值中的第一个 xx 字符。
    • 您还应该注意该表上的排序规则。如果您使用不区分大小写的排序规则(有时是默认排序规则),“Foo bar”将得到与“foo bar”相同的翻译。
    猜你喜欢
    • 2014-01-29
    • 1970-01-01
    • 2014-08-01
    • 2013-02-21
    • 2014-01-12
    • 2013-10-31
    • 2011-06-18
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多