从任何有实际经验的人看来,如果字段有一个普通的索引,那么在MySQL中数百万行表上的LIKE查询在速度和效率方面表现如何?

有没有更好的替代方案(不过滤结果,比如全文50%规则)可以在数百万行表上执行数据库字段搜索?

EXAMPLE:

Schema (comments table)

id (PRIMARY) title(INDEX) content time stamp

Query

SELECT * FROM 'comments' WHERE 'title' LIKE '%query%'

推荐答案

对于任何有实际经验的人来说,LIKE查询在

不太好(我想我有过900k的搜索量,不能说我有数百万行点赞的经验).

通常,您应该尽可能地限制搜索,但这取决于表 struct 和应用程序用例.

此外,在大约Web个用例中,可以使用一些技巧来实际提高性能和用户体验,比如为单独的关键字编制索引,并创建关键字表和rowcontainskeyword(id_keyword,id_row)表.关键字表与Ajax一起使用来建议搜索项(简单的单词),并将它们编译成整数--id_关键字.在这一点上,查找包含这些关键字的行变得更快了.一次更新表中的一行也相当有效;当然,批量更新会变成明确的"不要".

如果只使用+运算符,这与full text MATCH..IN BOOLEAN MODE已经执行的操作没有太大不同:

SELECT * FROM arts WHERE MATCH (title) AGAINST ('+MySQL +RDBMS' IN BOOLEAN MODE);

您可能需要一个InnoDB表来实现这一点:

布尔全文搜索具有以下特点:

  • 它们不会自动按相关性递减的顺序对行进行排序. ...
  • InnoDB表需要Match()表达式的所有列上的全文索引才能执行布尔查询.即使没有全文索引,针对MyISAM搜索索引的布尔查询也可以工作,尽管以这种方式执行的搜索会相当慢. ...
  • 它们不使用适用于MyISAM搜索索引的50%阈值.

你能提供更多关于具体案件的信息吗?

update: the AJAX way

设置:您将所有的title分成单词.这将很快为您提供title_words张桌子( id integer not null autoincrement, word varchar(50) )和一张很大的title_contains_word ( word_id integer, title_id integer )张桌子.

如果您有title_words0万个标题,平均4个单词(对于书籍来说似乎是合理的,而对于论文来说就不是这样了),那么您可以预期有一个5000行title_words行的表和一个包含两个整数列的4000万个表;这大约是400MB的额外数据.

对于搜索,用户开始输入一个单词,您可以从标题单词中 Select autocomplete个单词.一旦这样做了,查询就变成了一个单词ID列表;当然,不在任何标题中的单词都不能输入,所以立即免费地给出否定结果.

现在实际的搜索可以通过几种方式进行,但是我喜欢的一种方式是在每个用户 Select 之后运行SELECT COUNT(*) FROM title_contains_word WHERE word_id={id},before真正的搜索就开始了.

这允许构建从rarest个单词开始的复合查询或公用表表达式.实际上,如果任何单词的计数低于(比方说)20,您可以 Select 所有(平均)8个TCW行并获得它们所有相关单词的ID,然后只需(在MySQL之外)验证是否存在一个标题ID,以便查询的所有单词ID都存在一对(title ID,wordID).

即使你不得不诉诸最粗暴的形式,

SELECT a.title_id 
FROM title_contains_word AS tcw1
JOIN title_contains_word AS tcw2 USING (title_id)
JOIN title_contains_word AS tcw3 USING (title_id)
JOIN title_contains_word AS tcw4 USING (title_id)
...
WHERE (tcw1.word_id = {id1})
  AND (tcw2.word_id = {id2})
  ...

连接将由非常小的虚拟缓冲表组成,扫描所需的时间非常短.

一旦有了所有相关的标题ID,您就可以直接从多行大型DBusing the primary key title_id中运行SELECT.这最后一次搜索也应该是火速进行的.

Database相关问答推荐

触发器作为完整性的判断约束

芭蕾舞女演员坚持 1:N 关系

如何使用用户定义的字符串索引数据框?

如何在 C# 控制台应用程序中执行 CMD 命令?

Ruby on Rails:before_save 字段为小写

如何将 MySQL 5.5.40 升级到 MySQL 5.7

存储所有排列的模式数据库

两个不同数据库中的两个表之间的连接有什么问题?

单向和双向关系关系的区别

在数据库中存储枚举值的最佳方式 - String 或 Int

使用 jQuery 动态填写表单值

本地数据库,我需要一些例子

更改列名 Rails

将 Android Room 数据库与 Firebase 实时数据库相关联

如何使用 PHP 代码将图像上传到 MySQL 数据库

我可以用 JPA 命名我的约束吗?

我是否需要为关系数据库表的主键创建单独的索引

如何一次插入1000行

显式事务回滚是否必要?

包含 8000 万条记录并添加索引的表需要超过 18 小时(或永远)!怎么办?