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

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

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

  1. USERSEARCH
  2. -----------------------------------------------
  3. user_id(FK) username_ngram name_ngram
  4. 1 "AleBoy leBoy eBoy..." "Ale le e"
  5. 2 "craze123 raze123 ..." "Craze raze aze ze e"
  6. 3 "john1990 ohn1990 ..." "John ohn hn n"
  7. 4 "JJ_1 J_1 _1 1" "JJ"
  8. USERRELATIONSHIP
  9. -----------------------------------------------
  10. user_id(FK) follows_id(FK)
  11. 2 1
  12. 2 3

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

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

指数

  1. index(user_id)
  2. index(username_ngram)
  3. index(name_ngram)
  4. FULLTEXT(username_ngram, name_ngram)

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

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

7rfyedvj1#

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

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

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

6tdlim6h

6tdlim6h2#

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

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

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

  1. ( SELECT ... ORDER BY .. LIMIT 10 )
  2. UNION ALL
  3. ( SELECT ... ORDER BY .. LIMIT 10 )
  4. ORDER BY .. LIMIT 10

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

展开查看全部

相关问题