mysql - 替代 MySQL 全文搜索语法

标签 mysql full-text-search

如果您想要相关性以及按相关性对结果进行排序,全文查询的常见格式是:

SELECT name, MATCH(name) AGAINST('Bob') AS 相关性 FROM users WHERE MATCH(name) AGAINST('Bob')

作为一名开发人员,我总是喜欢让我的代码干燥(不要重复自己)。有什么理由不将查询编写为:

SELECT name, MATCH(name) AGAINST('Bob') AS 相关性 FROM 用户 HAVING 相关性 > 0 ORDER BY 相关性 DESC

它似乎返回相同的结果,但我应该担心 ORDER BY 导致查询变慢吗?这些查询等效吗?

正如 MySQL 手册中所述,指定 MATCH() 两次不会降低性能。

Natural Language Full-Text Searches

To achieve this result, you should specify MATCH() twice: once in the SELECT list and once in the WHERE clause. This causes no additional overhead, because the MySQL optimizer notices that the two MATCH() calls are identical and invokes the full-text search code only once.

最佳答案

不幸的是,根据MySQL SELECT documentation ,“HAVING 子句几乎是最后应用的,就在将项目发送到客户端之前,没有进行任何优化。”

不同之处在于,第一个查询将使用全文索引计算 name 中包含“Bob”的行的相关性。第二个查询将计算所有行的相关性,然后丢弃其中的大部分(可能在对整个表进行排序之后)。因此,第二个查询明显变慢。即使将 ORDER BY 子句放在第一个查询上,它仍然比使用 HAVING 更快:

SELECT name, MATCH(name) AGAINST('Bob') AS relevance
FROM users
WHERE MATCH(name) AGAINST('Bob')
ORDER BY relevance DESC

一般来说,“不要对应该在 WHERE 子句中的项目使用 HAVING。”

关于mysql - 替代 MySQL 全文搜索语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2245974/

相关文章:

php - 上传文件并使用 file_get_contents php 读取

mysql - 如何导入以单独字符结尾的行的 csv?

python - 如何使用 pymongo 将精确匹配词传递给 mongodb 查询?

mysql 搜索顶部匹配应该排在第一位

algorithm - map-reduce如何用于倒排索引搜索?

sqlite - 将 mysql 转储转换为 sqlite 兼容文件时出错

mySQLi 检查parent_category 是否匹配category_id = 0

mysql - 我如何使用连接来组合这两个查询?

database - 我们可以通过替换Postgres来使用Elastic Search作为后端数据存储吗?

ruby-on-rails - 如何使用 ActiveRecord 在 SQLite3 中设置 FTS 虚拟表?