【问题标题】:Search a text for multiple keywords在文本中搜索多个关键字
【发布时间】:2015-09-14 19:04:08
【问题描述】:

我需要在 English dictionary(大约 275,000 个关键字)中搜索文本(大约 500 个单词)来检测非英语单词,而现在我使用的查询并没有真正优化,需要超过 10 个执行秒数(有一个words 表和一个texts 表):

SELECT word FROM words WHERE 'The quick brown fox jumps over the lazy dog' LIKE CONCAT( '%', word, '%' );

here得到这个想法。

我已经将word 字段设置为索引,并看到了一些人们将文本存储在数据库中或将其直接放入查询的示例。

其他示例显示人们使用 FULLTEXT 搜索虽然有 300k 字我不认为 FULLTEXT 会工作,我想用逻辑搜索 +brown +lazy -apple 很好,但就我而言,我不需要太多逻辑。

Another example 我见过的是将单词与IN (...) 子句连接起来,尽管有 500m 个关键字,但查询会非常长。

有什么想法吗?

现在文本被保存为text 字段,单词在 InnoDB 中以utf8_unicode_ci 编码保存为varchar(50),我听说 InnoDB 很慢,所以我可以使用 MyISAM 或任何其他。我正在使用 MySQL 5.5,但如果有帮助,我可以更新到 5.6。

【问题讨论】:

  • 一定要用mysql做吗?
  • 用于 PHP/MySQL 网站

标签: php mysql


【解决方案1】:

LIKE 比较基本上只是支持通配符的相等性测试。它们不是通用的关键字搜索引擎。

WHERE foo LIKE '%a b%' 会在 foo 字段的任何位置找到包含文字文本 a b 的任何记录,它们不会单独查找 aba b 是一个单一的整体“单词”并且该词被完整搜索。

如果你想使用LIKE搜索多个“单词”,你必须这样做

WHERE foo LIKE '%a%' OR foo LIKE '%b%' OR etc...

很快就会变得丑陋,而且效率极低 - %... 搜索不能使用索引。

您最好改用fulltext 搜索系统,在那里您可以使用更简单的方法

WHERE MATCH(foo) AGAINST ('a b')

【讨论】:

  • 谢谢 Marc,MATCH AGAINST 的问题是我需要 275k OR 语句,这会导致很长的查询。你的意思是我应该做MATCH(text) AGAINST(word) 其中word 是来自MySQL 的字段?
  • 没有。这是match(field1, field2,....) against ('your text')。该文本可以是一个词,也可以是无数个词。
  • 哦,我明白了,参数搞混了。然而,查询仍然会非常长,如果存储在一个文件中,就像 50MB,并且需要我首先检索所有关键字并将它们连接起来。会不会有问题?
  • 我现在正在阅读文档,可以将word 字段作为参数传递。谢谢
  • 查询长度限制由 mysql 的 max_allowed_packet 设置控制。任何比这更大的东西都会被截断。
【解决方案2】:

当您开始处理数百万条记录时,InnoDB 会变得非常缓慢。这主要是由于它在访问表时如何锁定行。

我会使用 MyIsam,这样您就可以进行 FULLTEXT 搜索。也许是这样的:

    select word from words where match(text) against(word)

我不确定效率,但我不认为你真的需要使用你所说的逻辑。

编辑:

我的代码确实需要不止一次传递才能工作,因为第二个参数确实需要是所有单词。我想你可以在 SQL 中使用 FOR 循环来填充它,但我将不得不考虑执行此操作的代码。可能是游标或存储过程可以解决问题。

不过,我同意另一个答案,即您需要使用 FULLTEXT 搜索。

【讨论】:

    猜你喜欢
    • 2011-09-14
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2018-05-03
    • 1970-01-01
    • 2013-02-15
    相关资源
    最近更新 更多