WHERE 子句中条件的顺序会影响 MySQL 中的性能吗?
Can the order of criteria in a WHERE clause affect performance in MySQL?
给定以下查询:
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
放在第一位,然后再显示状态检查,性能是否相同?
让我们假设任何列上都没有索引来简化问题。
is just the same thing put the ilikes first and the status criteria later?
你可以通过运行 EXPLAIN 对照两者自己找出答案
您查询的版本。例如
EXPLAIN select ... from ... where
很可能你会得到两个完全相同的执行计划,这意味着这两个语句是等价的,因为状态部分应该被 dead code elimination optimization.
删除
(部分回答,部分询问更多信息...)
将status=1
放在最前面或最后没有区别。换句话说,WHERE
中 ANDed
事物的顺序并不重要。
LOWER(x) LIKE '...'
比将 x
的排序规则设置为大小写折叠效率低得多,例如 utf8_general_ci
(ci
表示 "case insensitive" ).使用 ci
归类,您只需要 x LIKE '...'
.
但是,这不会加快速度。你有很多ORs
;这些效率低下,因为索引 通常 无用,因此需要进行完整的 table 扫描。
通常,OR
可以变成 UNION
以便能够使用索引。但可能不是你的情况。
请提供SHOW CREATE TABLE
。嗯......查询的模式让我想知道你是否有很多 'identical' tables。如果是这样,也许我们可以将其视为设计模式的低效方法。所以,请告诉我们 c01
和 c03
(等)是否相同。
什么样的值会被放入LIKEs
?字?数字?任意字符串?通配符?前导通配符?不领先?如果 "words",那么 FULLTEXT
可能 有用。但是...我们需要仔细查看涉及的 table 的长(?)列表。
放置条件的顺序可以因为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
故意休眠一秒钟,并具有每次 运行 时向日志 table 添加条目的副作用。以下是 运行 执行上述两个查询时记录的结果:
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
检查之前,因为(除了索引)它可能会被更快地评估。
你应该把基数最小的条件放在最前面。这会过滤行数以浏览到更小的数字。
SQL是一种声明式语言,你只关心"what to do",所以你不关心必须担心 "how" 您的查询将要执行,DBMS 会处理并选择 最佳执行计划 , 所以简短的回答是顺序没有区别。
给定以下查询:
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
放在第一位,然后再显示状态检查,性能是否相同?
让我们假设任何列上都没有索引来简化问题。
is just the same thing put the ilikes first and the status criteria later?
你可以通过运行 EXPLAIN 对照两者自己找出答案 您查询的版本。例如
EXPLAIN select ... from ... where
很可能你会得到两个完全相同的执行计划,这意味着这两个语句是等价的,因为状态部分应该被 dead code elimination optimization.
删除(部分回答,部分询问更多信息...)
将status=1
放在最前面或最后没有区别。换句话说,WHERE
中 ANDed
事物的顺序并不重要。
LOWER(x) LIKE '...'
比将 x
的排序规则设置为大小写折叠效率低得多,例如 utf8_general_ci
(ci
表示 "case insensitive" ).使用 ci
归类,您只需要 x LIKE '...'
.
但是,这不会加快速度。你有很多ORs
;这些效率低下,因为索引 通常 无用,因此需要进行完整的 table 扫描。
通常,OR
可以变成 UNION
以便能够使用索引。但可能不是你的情况。
请提供SHOW CREATE TABLE
。嗯......查询的模式让我想知道你是否有很多 'identical' tables。如果是这样,也许我们可以将其视为设计模式的低效方法。所以,请告诉我们 c01
和 c03
(等)是否相同。
什么样的值会被放入LIKEs
?字?数字?任意字符串?通配符?前导通配符?不领先?如果 "words",那么 FULLTEXT
可能 有用。但是...我们需要仔细查看涉及的 table 的长(?)列表。
放置条件的顺序可以因为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
故意休眠一秒钟,并具有每次 运行 时向日志 table 添加条目的副作用。以下是 运行 执行上述两个查询时记录的结果:
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
检查之前,因为(除了索引)它可能会被更快地评估。
你应该把基数最小的条件放在最前面。这会过滤行数以浏览到更小的数字。
SQL是一种声明式语言,你只关心"what to do",所以你不关心必须担心 "how" 您的查询将要执行,DBMS 会处理并选择 最佳执行计划 , 所以简短的回答是顺序没有区别。