此查询(使用不同的名称而不是“jack”)在我的慢查询日志中多次出现。为什么呢?
Users表有很多字段(超过我选择的这三个字段)和大约40.000行。
select name,username,id from Users where ( name REGEXP
'[[:<:]]jack[[:>:]]' ) or ( username REGEXP '[[:<:]]jack[[:>:]]' )
order by name limit 0,5;
id
是主要的和自动增量
name
有一个索引
username
有一个唯一的索引。
有时需要3秒钟! 如果我解释MySQL上的选择我得到了这个:
select type: SIMPLE
table: Users
type: index
possible keys: NULL
key: name
key len: 452
ref: NULL
rows: 5
extra: Using where
这是我能做的最好的吗?我能解决什么?
答案 0 :(得分:14)
如果你必须使用regexp风格的WHERE
子句,你肯定会受到慢查询问题的困扰。要使regexp样式的搜索起作用,MySQL必须将名称列中的每个值与regexp进行比较。而且,通过查看用户名列,您的查询也增加了麻烦。
这意味着MySQL无法利用任何索引,这就是所有DBMS加速查询大型表的方式。
您可以尝试一些方法。所有这些都涉及向REGEXP道别。
一个是这个:
WHERE name LIKE CONCAT('jack', '%') OR username LIKE CONCAT('jack', '%')
如果您在名称和用户名列上创建索引,这应该会非常快。它将查找以“jack”开头的所有名称/用户名。注意
WHERE name LIKE CONCAT('%','jack') /* SLOW!!! */
会查找以'jack'结尾的名称,但会像你的正则表达式搜索一样慢。
您可以做的另一件事是找出您的应用程序需要能够搜索部分名称或用户名的原因。您可以从应用程序中删除此功能,或者找出一些更好的方法来处理它。
可能更好的方法:
所有这些都涉及一些编程工作。
答案 1 :(得分:2)
我通过在where子句中添加fieldname
!=''来达到50%的加速。它使mysql使用索引。
SELECT name, username, id
FROM users
WHERE name != ''
AND (name REGEXP '[[:<:]]jack[[:>:]]' or username REGEXP '[[:<:]]jack[[:>:]]')
ORDER BY name
LIMIT 0,5;
不是一个完美的解决方案,但有帮助。
答案 2 :(得分:-3)
在前面添加“LIKE”
这
SELECT cat_ID, categoryName FROM category WHERE cat_ID REGEXP '^15-64-8$' ORDER BY categoryName
到
SELECT cat_ID, categoryName FROM category WHERE cat_ID LIKE '15-64-8%' and cat_ID REGEXP '^15-64-8$' ORDER BY categoryName
总之,只有当你搜索短语时,才知道你知道的是什么,否则全文索引就是解决方案。