我需要在英语词典(约275,000个关键字)中搜索文本(约500个单词长)以检测非英语单词,现在我使用的查询并没有真正优化,需要超过10秒才能执行(有一个words
表和一个texts
表):
SELECT word FROM words WHERE 'The quick brown fox jumps over the lazy dog' LIKE CONCAT( '%', word, '%' );
我明白了。
我已经将word
字段设置为索引,并看到了人们将文本存储在数据库中或将其直接放入查询中的一些示例。
其他例子显示人们使用FULLTEXT搜索,虽然有30万字,我不认为一个FULLTEXT将工作,我想这是很好的搜索逻辑+brown +lazy -apple
,但在我的情况下,我不需要太多的逻辑。
我看到的另一个例子是用IN (...)
子句连接单词,尽管有500个关键字,查询将会非常长。
有什么主意吗?
现在文本被保存为text
字段和varchar(50)
在utf8_unicode_ci
编码的InnoDB中的单词,我听说InnoDB很慢,所以我可以使用MyISAM或任何其他。我正在使用MySQL 5.5,虽然我可以更新到5.6,如果有帮助的话。
LIKE
比较基本上只是通配符功能的相等性测试。他们不是一个通用的关键字搜索引擎。
WHERE foo LIKE '%a b%'
将在foo字段的任何地方找到包含文字a b
的任何记录,它们不会单独查找a
或b
, a b
是一个单一的整体"单词",并且该单词将被完整地搜索。
如果你想用LIKE
搜索多个"words",你必须执行
WHERE foo LIKE '%a%' OR foo LIKE '%b%' OR etc...
很快就会变得丑陋,而且效率极低- %...
搜索不能使用索引。
你最好切换到全文搜索系统,在那里你可以有更简单的
WHERE MATCH(foo) AGAINST ('a b')
当您开始处理数百万条记录时,InnoDB可能会变得非常慢。这主要是由于它在访问表时如何锁定行。
我会使用MyIsam,这样你就可以做一个全文搜索。比如:
select word from words where match(text) against(word)
我不确定效率,但你真的不需要使用你所说的逻辑,我不认为。
编辑:我的代码真的需要有不止一个传递才能工作,因为第二个参数真的需要是所有的单词。我想,您可以在SQL中使用FOR循环来填充它,但我必须考虑如何编写代码。也许游标或存储过程就可以了。
我同意另一个答案,不过,你需要使用FULLTEXT搜索。