如何在mysql中将查询集限制为ID的子集?

fwzugrvs  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(474)

我有一个usersearch表,应该用于用户的快速子字符串搜索。此功能用于在键入用户名或名称时自动完成搜索。但是,我感兴趣的查询将只显示该用户所关注的用户的匹配项。

USERSEARCH
-----------------------------------------------
user_id(FK)    username_ngram          name_ngram
1              "AleBoy leBoy eBoy..."  "Ale le e"
2              "craze123 raze123 ..."  "Craze raze aze ze e"
3              "john1990 ohn1990 ..."  "John ohn hn n"
4              "JJ_1 J_1 _1 1"         "JJ"

USERRELATIONSHIP
-----------------------------------------------
user_id(FK)    follows_id(FK)
2              1
2              3

以下查询是在某人刚键入“al”时执行的:

SELECT * FROM rage.usersearch where username_ngram like 'Al%' --1
UNION DISTINCT
SELECT * FROM rage.usersearch where name_ngram like 'Al%'  --2
UNION DISTINCT
SELECT * FROM rage.usersearch                             --3
WHERE MATCH (username_ngram, name_ngram) AGAINST ('Al')  
LIMIT 10

指数

index(user_id)
index(username_ngram)
index(name_ngram)
FULLTEXT(username_ngram, name_ngram)

有没有办法限制上面的查询只查看这个用户id子集(每个子查询不查询3次)?

SELECT follows_id FROM rage.userrelationship WHERE user_id={user_id of user doing the searching}
7rfyedvj

7rfyedvj1#

mysql只能对每个表引用使用一个索引。它也可以只使用一个范围扫描每个索引。因此,无论是两列上的两个单独索引,还是两列上的一个复合索引,都不会阻止全表扫描。全文索引不适用于 LIKE . 优化此查询的最佳方法是在联合查询中组合两个单独的搜索:

SELECT user_id FROM myapp.usersearch WHERE username_ngram LIKE '{string}%'
UNION DISTINCT
SELECT user_id FROM myapp.usersearch WHERE name_ngram LIKE '{string}%'

发动机现在可以使用 INDEX(username_ngram) 对于第一个查询部分 INDEX(name_ngram) 第二次。

6tdlim6h

6tdlim6h2#

如果你要接收字符串的前几个字母,我看不出ngram的用处。
在这一点上,这是最佳的:

SELECT ... WHERE name LIKE 'Al%'
    LIMIT 10;

INDEX(name) .
如果你需要使用 UNION ALL 一起 LIMIT ,然后执行以下操作:

( SELECT ... ORDER BY .. LIMIT 10 )
UNION ALL
( SELECT ... ORDER BY .. LIMIT 10 )
ORDER BY .. LIMIT 10

如果你不重复 LIMIT 每个子查询将收集所有相关的行,从而创建一个大于所需的临时表。
如果你要用 OFFSET (可能不适用于此应用程序),请参阅以下内容了解如何使其工作:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#or

相关问题