WHERE子句中的条件顺序是否会影响MySQL的性能?

时间:2016-11-08 14:24:01

标签: mysql sql performance where-clause sql-like

给出以下查询:

select ....................
from ......................
where 
(
      lower(c01) like ? 
      or lower(c02) like ? 
      or lower(c5x3_.c01) like ? 
      or lower(5x3_.c02) like ?
 )    
 and(
(
      lower(c03) like ? 
      or lower(c04) like ? 
      or lower(c5x3_.c03) like ? 
      or lower(5x3_.c04) like ?
 )    
 /* ...Multiple further LIKEs... */
 and status=1; /* status is a non-nullable value whose values can only be 1 or 2 */

对于各种模式,前10或12个限制是LIKE - 我知道这可能很慢,所以总是把状态标准放在首位,即:

status=1;
 and(other LIKEs)

我的问题:首先应用更简单的限制是否会有性能提升(例如,在这种情况下,被比较的int值可以是空值而且只有2个可能的值)?如果首先放置LIKE并稍后显示状态检查,那么性能是否相同?

假设任何列都没有索引来简化问题。

5 个答案:

答案 0 :(得分:4)

(部分答案,部分要求提供更多信息......)

status=1放在第一位还是最后一位,没有区别。换句话说,ANDedWHERE项的顺序并不重要。

LOWER(x) LIKE '...'效率低于将x的整理设置为大小写折叠,例如utf8_general_cici表示"不区分大小写&# 34)。使用ci排序规则,您只需x LIKE '...'

但是,这不会让事情变得更快。你有很多ORs;这些效率很低,因为索引通常无用,因此需要进行全表扫描。

通常,OR可以转换为UNION以便能够使用索引。但可能不是你的情况。

请提供SHOW CREATE TABLE。嗯...查询的模式让我想知道你是否有很多相同的'表。如果是这样,也许我们可以将其作为设计模式的低效方式。因此,请告诉我们c01c03(等)是否相同。

LIKEs会添加哪些值?话?数字?任意字符串?通配符?领先的通配符?不领先?如果"单词",那么FULLTEXT 可能有用。但是......我们需要仔细研究所涉及的长(?)表列表。

答案 1 :(得分:3)

由于MySQL短路,条件的顺序可以产生差异。这是试图证明这一点:

http://rextester.com/HJGN96158

这将运行以下查询:

SELECT myint FROM mytable WHERE myint >= 3 AND myslowfunction('query #1', myint) = 1;
SELECT myint FROM mytable WHERE myslowfunction('query #2', myint) = 1 AND myint >= 3;

这些之间的唯一区别是AND条件中操作数的顺序。

myslowfunction故意睡眠一秒,并且每次运行时都会在日志表中添加一个条目。以下是运行上述两个查询时记录的结果:

myslowfunction called for query #1 with value 3
myslowfunction called for query #1 with value 4
myslowfunction called for query #2 with value 1
myslowfunction called for query #2 with value 2
myslowfunction called for query #2 with value 3
myslowfunction called for query #2 with value 4

上面显示当一个慢速函数出现在AND条件的左侧时,当另一个操作数不总是为假(由于短路)时,它会被执行多次。

从这一点来看,我的建议是在status = 1检查之前将LIKE检查为(除了索引),它可能会更快地进行评估。

答案 2 :(得分:2)

  

将ilikes放在第一位,将状态标准放在后面是同样的事情吗?

您可以通过对两者运行EXPLAIN来自行找到答案 您的查询的版本。 E.g。

EXPLAIN select ... from ... where

很可能你会得到两个完全相同的执行计划,这意味着两个语句是等价的,因为状态部分应该被dead code elimination optimization删除。

答案 3 :(得分:2)

SQL是声明性语言,您只关心&#34;该怎么做&#34; ,所以您不必担心<强>&#34;如何&#34; 您的查询将被执行,DBMS将负责并选择最佳执行计划,所以简短的答案是没有差别。

答案 4 :(得分:0)

您应该首先使用最小基数的条件。这会过滤要浏览的较小数量的行数。