Pon*_*ons 6 regex mysql indexing optimization query-optimization
在我的慢查询日志中,此查询(使用不同的名称而不是"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
Run Code Online (Sandbox Code Playgroud)
这是我能做的最好的吗?我能解决什么?
O. *_*nes 15
如果你必须使用regexp-style WHERE子句,你肯定会受到慢查询问题的困扰.要使regexp样式的搜索起作用,MySQL必须将名称列中的每个值与regexp进行比较.而且,通过查看用户名列,您的查询也增加了麻烦.
这意味着MySQL无法利用任何索引,这就是所有DBMS加速大型表查询的方式.
你可以尝试一些事情.所有这些都涉及到REGEXP说再见.
一个是这样的:
WHERE name LIKE CONCAT('jack', '%') OR username LIKE CONCAT('jack', '%')
Run Code Online (Sandbox Code Playgroud)
如果您在名称和用户名列上创建索引,这应该会非常快.它将查找以"jack"开头的所有名称/用户名.请注意
WHERE name LIKE CONCAT('%','jack') /* SLOW!!! */
Run Code Online (Sandbox Code Playgroud)
将查找以'jack'结尾的名称,但会像你的正则表达式搜索一样慢.
您可以做的另一件事是弄清楚为什么您的应用程序需要能够搜索名称或用户名的一部分.您可以从应用程序中删除此功能,或者找出一些更好的方法来处理它.
可能更好的方法:
所有这些都涉及一些编程工作.