MySQL 是否短路了 IF() 函数?

发布于 2024-09-19 11:59:43 字数 256 浏览 3 评论 0原文

我需要从第二个表查询数据,但前提是满足主表中的一组罕见条件:

SELECT ..., IF(a AND b AND c AND (SELECT 1 FROM tableb ...)) FROM tablea ...

a、b 和 c 条件几乎总是 false,所以我的想法是子查询永远不会对结果集,因此比连接快得多。但只有当 IF() 语句短路时才会出现这种情况。

是吗?

感谢你们提供的任何帮助。

I need to query data from a second table, but only if a rare set of conditions in the primary table is met:

SELECT ..., IF(a AND b AND c AND (SELECT 1 FROM tableb ...)) FROM tablea ...

a, b, and c conditions are almost always false, so my thinking is the subquery will never execute for most rows in the result set and thus be way faster than a join. But that would only true if the IF() statement short circuits.

Does it?

Thanks for any help you guys can provide.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦断已成空 2024-09-26 12:00:08

在 SQL 分析器中尝试一下。如果您想安全起见,并且不必相信数据库以一种方式工作(并且不要在新版本中更改该行为),只需进行两个查询并以编程方式执行 IF 即可。

Try it in the SQL analyzer. If you want to be on the safe side and not have to trust the database to work one way (and not to change that behavior ever in new versions), just make two queries and do the IF programmatically.

美人如玉 2024-09-26 12:00:04

这取决于。

IF 不会短路,因此可以用来避免 GROUP_CONCAT 的截断警告,例如:

set @@group_concat_max_len = 5;

select if(true or @var:=group_concat('warns if evaluated'), 'actual result', @var);

结果将是“实际结果”,但您会收到警告:

Warning (Code 1260): Row 1 was cut by GROUP_CONCAT()

这与您在不那么琐碎的情况下收到的警告相同GROUP_CONCAT 表达式,例如不同的键,并且根本没有 IF。

It depends.

IF doesn't short-circuit such that it can be used to avoid truncation warnings with GROUP_CONCAT, for example in:

set @@group_concat_max_len = 5;

select if(true or @var:=group_concat('warns if evaluated'), 'actual result', @var);

the result will be 'actual result' but you'll get a warning:

Warning (Code 1260): Row 1 was cut by GROUP_CONCAT()

which is the same warning you get with less trivial GROUP_CONCAT expressions, such as distinct keys, and without the IF at all.

乖乖 2024-09-26 12:00:00

在 J. Jorgenson 的帮助下,我提出了自己的测试用例。他的例子并没有试图在条件评估中短路,但是利用他的想法我想出了自己的测试并验证MySQL确实短路了IF()条件检查。

SET @var:=5;
SELECT IF(1 = 0 AND (@var:=10), 123, @var); #Expected output: 5
SELECT IF(1 = 1 AND (@var:=10), @var, 123); #Expected output: 10

在第二个示例中,MySQL 正确短路:@var 永远不会设置为 10。

感谢 J. Jorgenson 的帮助!

With J. Jorgenson's help I came up with my own test case. His example does not try to short circuit in the condition evaluation, but using his idea I came up with my own test and verified that MySQL does indeed short-circuit the IF() condition check.

SET @var:=5;
SELECT IF(1 = 0 AND (@var:=10), 123, @var); #Expected output: 5
SELECT IF(1 = 1 AND (@var:=10), @var, 123); #Expected output: 10

On the second example, MySQL is properly short-circuiting: @var never gets set to 10.

Thanks for the help J. Jorgenson!

傲娇萝莉攻 2024-09-26 11:59:56

答案是肯定的。
mysql 查询中的 IF(cond,expr_true,expr_false) 是短路的。

这里是一个测试,使用 @variables 来证明事实:

SET @var:=5;  
SELECT IF(1 = 0, (@var:=@var + 1), @var ); -- using ':=' operator to modify 'true' expr @var 
SELECT IF(1 = 1, @var, (@var:=@var + 1) ); -- using ':=' operator to modify 'false' expr @var 
SELECT @var;

所有三个 SELECT 查询的结果都是“5”。

如果 IF() 函数没有短路,则结果将是 SELECT #1 中的“5”、SELECT #2 中的“6”以及最后一个“select @var”中的“7”。

这是因为在 select #1 中永远不会执行“true”表达式,而在 select #2 中也不会执行 false 表达式。

请注意,“:=”运算符用于在 SQL 查询(select、from 和 where 子句)中修改 @var。你可以从中得到一些非常奇特/复杂的 SQL。我使用 @vars 在 SQL 查询中应用“过程”逻辑。

——J·乔根森——

The answer is YES.
The IF(cond,expr_true,expr_false) within a mysql query is short-circuited.

Here a test, using @variables to prove the fact:

SET @var:=5;  
SELECT IF(1 = 0, (@var:=@var + 1), @var ); -- using ':=' operator to modify 'true' expr @var 
SELECT IF(1 = 1, @var, (@var:=@var + 1) ); -- using ':=' operator to modify 'false' expr @var 
SELECT @var;

The result is '5' from all three SELECT queries.

Had the IF() function NOT short circuited, the result would be a '5' from SELECT #1, and '6' from SELECT #2, and a '7' from the last "select @var".

This is because the 'true' expression is NEVER executed, in select #1 and nor is the false expression executed for select #2.

Note the ':=' operator is used to modify an @var, within an SQL query (select,from, and where clauses). You can get some really fancy/complex SQL from this. I've used @vars to apply 'procedural' logic within a SQL query.

-- J Jorgenson --

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文