【问题标题】:Alternative MySQL fulltext search syntax替代 MySQL 全文搜索语法
【发布时间】:2010-02-11 16:40:38
【问题描述】:

如果您希望相关性以及按相关性对结果进行排序,FULLTEXT 查询的常用格式是:

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

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

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

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

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

Natural Language Full-Text Searches

要达到这个结果,你应该 指定MATCH() 两次:一次在 SELECT 列表和一次在 WHERE 条款。这不会导致额外的 开销,因为 MySQL 优化器 注意到两个MATCH() 调用是 相同并调用全文 只搜索一次代码。

【问题讨论】:

    标签: mysql full-text-search


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我尝试使用 WHERE 相关性 > 0 但随后出现此错误 Unknown column 'relevance' in 'where Clause'
    • 是的。 WHERE 子句是在 SELECT 表达式之前计算的,因此它不能为这些表达式使用任何别名。 HAVING 子句在之后执行,因此它可以使用这些别名;然而,只有 WHERE 子句可以让 MySQL 优化掉无用的计算。在这种情况下,DRY 或速度:任你选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多