mysql LIKE查询时间过长

zte4gxcn  于 2023-10-15  发布在  Mysql
关注(0)|答案(6)|浏览(179)

SQL:

  1. SELECT
  2. COUNT(usr.id) as `total_results`
  3. FROM
  4. users as usr
  5. LEFT JOIN profile as prof
  6. ON prof.uid = usr.uid
  7. WHERE
  8. usr.username LIKE '%a%'
  9. OR
  10. prof.name LIKE '%a%'

用户索引:

  1. uid - uid
  2. username - username

配置文件上的索引

  1. index1 - uid
  2. index2 - uid,name
  3. index3 - name

解释:

  1. id select_type table type possible_keys key key_len ref rows Extra
  2. 1 PRIMARY usr ALL NULL NULL NULL NULL 18387
  3. 1 PRIMARY prof ref index2,index1 index2 8 site.usr.uid 1 Using where
  4. 2 DEPENDENT SUBQUERY sub ref i3,index1,index2 i3 16 site.usr.uid,const 1 Using index

上述查询需要大约0.1221
怎么才能让它跑得快一点呢?

z3yyvxxp

z3yyvxxp1#

要匹配的字符串开头的%使其无法使用索引。在开始处的索引无效,MySQL必须在该列中搜索 * 每 * 行。它不能跳下去。如果您知道要搜索的项目将位于字段开头的开头,则可以删除开头的“%”。
但是,如果你正在搜索“steve”,我的回答将返回“steve”,“steven”,"steve-boss“,而不是”boss-steve“或”realsteve“。

xwbd5t1u

xwbd5t1u2#

LIKE子句中的初始值%意味着不能使用这些列的索引。我相信MySQL full text index可以做到你想要的。

ctzwtxfj

ctzwtxfj3#

它尽可能多地使用索引(左连接的两个主键)。主要问题是LIKE '%a %',因为在这种情况下,它不能使用索引(如果它是'a %',它将能够使用用户名和名称的索引)。你可以尝试(不确定这是否会加快速度)使用concat(usr.username,prof.name),比如'%a %',但你可能不会注意到任何区别。
全文索引将不起作用,因为全文索引在搜索整个单词时很有用。
无论如何,对于查询,你有你的索引名称和用户名是无用的,只是占用空间,所以我会删除它们。如果LIKE 'a%'满足您的需求,那么这些索引就有意义了。
如果'a%'不能满足你的需求,你可以看看其他选项,例如mysql查询缓存(如果你希望频繁重复查询)。

ktecyv1j

ktecyv1j4#

1)购买更快的数据库服务器。
2)重新设计你的数据库,这样你就不必在两个地方寻找用户名,或者只允许用户在其中一个地方搜索

aiqt4smr

aiqt4smr5#

我删除了这个查询,所以它不会显示总结果计数时,搜索完成。
这似乎是一个暂时的解决方案,甚至是永久的。

dgjrabp2

dgjrabp26#

在我的情况下,当使用带有前导' %'的'like'运算符时,'Value'字段上的索引会减慢选择速度:

  1. select distinct My_Value
  2. from My_Table
  3. where My_Value like '%a%';

如果我删除索引,同样的查询运行得很快。但我需要索引来应付其他情况。
在研究中发现了“忽略索引”命令,并重写了查询,问题解决了:

  1. select distinct My_Value
  2. from My_Table Ignore Index (My_Index)
  3. where My_Value like '%a%';

有关使用“忽略索引”的更多信息:https://dev.mysql.com/doc/refman/8.0/en/index-hints.html

相关问题