2010-02-11 34 views
0

如果你想相关性,同时将结果按相关性进行排序的全文查询的通用格式是:替代MySQL的全文搜索语法

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()调用是 相同并且仅调用一次全文 搜索代码。

回答

1

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

区别在于第一个查询将使用全文索引来计算相关性只有行中有'Bob'name。第二个查询将计算所有行的相关性,然后丢弃其中的大部分(可能在对整个表进行排序后)。因此,第二个查询显着较慢。即使你把ORDER BY子句到第一查询时,它仍然会比使用具有速度快:“请不要使用具有的项目应该是在WHERE子句中”

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

一般情况下,

+0

我试过使用WHERE相关性> 0但是然后我得到这个错误'where子句'中的未知列'相关性' – ejunker 2010-02-11 18:46:18

+0

是的。 WHERE子句在SELECT表达式之前计算*,因此它不能为这些表达式使用任何别名。 HAVING子句在执行后执行,因此可以使用这些别名;然而,只有WHERE子句可以让MySQL优化无用的计算。 在这种情况下,DRY或速度:请选择。 – eswald 2010-02-11 19:06:10