全文搜索按相关性分数排序
Posted
技术标签:
【中文标题】全文搜索按相关性分数排序【英文标题】:Full text search sort by relevancy score 【发布时间】:2016-09-19 10:56:08 【问题描述】:表: users
与 full text search
列 username
上的索引。
查询:
SELECT
MATCH (username) AGAINST ('shaharyar' IN NATURAL LANGUAGE MODE) AS `score`,
uid,
first_name,
username,
`status`,
created
FROM users
WHERE
MATCH (username) AGAINST ('shaharyar' IN NATURAL LANGUAGE MODE) AND
uid <> 164125 -- to prevent self profile search
ORDER BY
score DESC,
created DESC
问题:Match
子句会执行2次吗?
我知道 mysql 默认按score
降序排序,但这里我需要双重排序条件,这就是我选择该列的原因。
解释扩展:
+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+
| 1 | SIMPLE | users | fulltext | PRIMARY,username | username | 0 | | 1 | 100 | Using where; Using filesort |
+----+-------------+-------+----------+------------------+----------+---------+-----+------+----------+-----------------------------+
表格中有大约 150K+ 条记录。
【问题讨论】:
【参考方案1】:是和不是。
WHERE MATCH...
将被执行若干次,从而“过滤”掉不“匹配”的行。只有剩余的行需要再次执行MATCH
。
另一方面,HAVING
必须对所有行(具有该 uid 的行除外)执行MATCH
,构建一个包含所有这些行的临时表。只有这样HAVING
才能进行过滤。
因此,即使MATCH
在HAVING
版本中执行的次数更少,查询也可能会运行得更快。
你确实有FULLTEXT(username)
,不是吗?
为什么,为什么,对一个词使用全文查询??
【讨论】:
如果我创建一个包含所有过滤行的临时表以在它们上应用HAVING
,它会不会与我当前的查询相同?或者我可能理解错了。除了这只是最小的例子,我将逻辑映射到其他场景。
这将与您的原始查询基本相同 - 只是因为显式创建 tmp 表而变慢。
这意味着我可以说我当前的查询非常适合该场景,并且没有办法在 SELECT 子句中获得 WHERE 条件?【参考方案2】:
我认为是的。这通常使用having
子句编写:
SELECT MATCH (username) AGAINST ('shaharyar' IN NATURAL LANGUAGE MODE) AS `score`,
uid, first_name, username, `status`, created
FROM users
WHERE uid <> 164125 -- to prevent self profile search
HAVING score > 0
ORDER BY score DESC, created DESC;
【讨论】:
很遗憾,您的查询没有使用索引(通过解释检查)。扫描 86K+ 行。我认为它的原因是条件不在 WHERE 子句中,而是在子句之后。以上是关于全文搜索按相关性分数排序的主要内容,如果未能解决你的问题,请参考以下文章