我在Mysql中运行查询,如此(混淆名称)
explain
select this_.id as id1_0_,
this_.column1 as column1,
this_.column2 as column2,
this_.column3 as column3,
this_.column4 as column4,
this_.column5 as column5,
from
tablename this_
where
this_.column1 like '/blah%'
and this_.column2 = 'a9b51a14-4338-94f7-f23dbf9d539e'
and this_.column3 <> 'DUH'
and this_.column4=0
and this_.column5 like '%somename%'
order by this_.created desc
limit 20
编辑:column1有一个BTREE索引,column2,column3,column4,column5,创建都有HASH索引。
表有一个外键,它在select子句中选择,但不在WHERE子句中选择。
我告诉并读了
喜欢%somename%
将导致全表扫描。但是,当我运行解释时,解释的输出是
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE this_ ref somecolumnandinexnames 111 const 30414 Using where
如果我删除了like子句,则解释输出看起来完全相同。
基于此,我们决定将查询投入生产中,以发现在实践中使用之类的的查询执行的时间更长(与没有类似的毫秒相比,几秒钟)。 / p>
有没有解释为什么说明事先没有提醒过我这个?
修改:观察
正如@Uueerdo所说,将其余条件转移到子查询中实际上可以提高性能!因此,我很想得出结论,可能发生的事情之一就是在导致大结果集的其他条件之前执行具有类似功能的WHERE子句。正如@Uueerdo所说,将其余条件转移到子查询中实际上可以提高性能!因此,我很想得出结论,可能发生的事情之一就是在导致大结果集的其他条件之前执行具有类似功能的WHERE子句。但是,我仍然没有解释为什么通过提高性能来删除订单。查询选择所有10行,因此顺序应该非常快。
有没有办法可以看到MYSQL评估查询的顺序。我想我记得曾经在MS SQL Server解释计划中看过某种图形表示。不要记得它是否完全一样。
答案 0 :(得分:3)
即使不需要进行表扫描,它仍然很昂贵;可能发生的事情是MySQL在where
中使用其他条件进行初始候选行选择,然后在其余条件下减少这些结果。
如果有大量候选人,和/或column5
值很长,那么这个条件可能需要一些时间来评估。请记住,LIMIT发生在WHERE之后,因此不会减少所需的工作量。
如果您将大部分查询放在子查询中, 可能 会看到一些改进,并根据外部查询中的like '%somename%'
条件对其结果进行过滤。
类似的东西:
SELECT * FROM (
SELECT t.id as id1_0_
, t.column1, t.column2, t.column3, t.column4, t.column5
, t.created
FROM tablename AS t
WHERE t.column2 = 'a9b51a14-4338-94f7-f23dbf9d539e'
AND t.column3 <> 'DUH'
AND t.column4=0
AND t.column1 like '/blah%'
) AS subQ
WHERE subQ.column5 like '%somename%'
ORDER BY subQ.created DESC
LIMIT 20
答案 1 :(得分:0)
如果您的索引包含所有正在读取的列(在SELECT
或WHERE
子句中),MySQL将能够从索引中读取所有这些值,而无需扫描表
另请注意,所有主键列也将位于索引中。
在这种情况下,即使它不扫描整个表,它也会扫描索引中的每一行以处理LIKE '%somename%'
查询,因此它不会特别有效率。