gpt4 book ai didi

MYSQL "Division by zero"警告,奇怪的行为

转载 作者:行者123 更新时间:2023-12-05 03:21:31 28 4
gpt4 key购买 nike

我正在使用 MySQL 8.0。

我创建了以下表格

SET SESSION sql_mode='ERROR_FOR_DIVISION_BY_ZERO';

create table Test(
col1 integer,
col2 integer
);

create table Test1(
colA integer,
colB varchar(45)
);

我用这些值填充了它们:

Test     Test1
1 2 2 a
3 4 4 b
1 5
1 2
0 4
0 2

现在,从其他答案中,我知道,一般来说,我不能依赖短路,因为 SQL 是一种声明性语言,因此您指定什么您不想要如何:留给 rdbms 优化器,它可以自由地重新排列条件的顺序。

我针对 Test 执行了以下查询表:

SELECT *
FROM Test
WHERE col2/col1>0 AND col1<>0;

SHOW WARNINGS;

我有两个关于两个除以零的警告(如预期的那样),这与上述查询的执行计划中报告的执行顺序相匹配:

"attached_condition": "(((`prova`.`test`.`col2` / `prova`.`test`.`col1`) > 0) and 
(`prova`.`test`.`col1` <> 0))"

这清楚地表明 col2/col1>0col1<>0 之前检查

然后我对上面的表运行了以下查询:

SELECT *
FROM Test T JOIN Test1 T1 ON T.col2=T1.colA
WHERE T.col2/T.col1>0 AND T.col1<>0;

而且这一次我预计会出现关于被零除的警告但是,令我惊讶的是,尽管查询执行计划表明带除法的条件是在检查 col1<>0 之前执行的:

"attached_condition": "((`prova`.`t`.`col2` = `prova`.`t1`.`colA`) and 
((`prova`.`t1`.`colA` / `prova`.`t`.`col1`) > 0) and (`prova`.`t`.`col1` <> 0))"

这怎么可能?

最佳答案

执行 EXPLAIN ANALYSE on the last query 时,这是输出:

-> Filter: ((T1.colA / T.col1) > 0)  (cost=1.00 rows=0) (actual time=0.047..0.061 rows=3 loops=1)
-> Inner hash join (T.col2 = T1.colA) (cost=1.00 rows=0) (actual time=0.039..0.051 rows=3 loops=1)
-> Filter: (T.col1 <> 0) (cost=0.23 rows=1) (actual time=0.006..0.015 rows=4 loops=1)
-> Table scan on T (cost=0.23 rows=6) (actual time=0.004..0.012 rows=6 loops=1)
-> Hash
-> Table scan on T1 (cost=0.45 rows=2) (actual time=0.015..0.019 rows=2 loops=1)

首先执行内部 Action 。在这里我们看到来自 T 的记录首先由 T.col1 <> 0 过滤然后它们才与来自 T1 的记录相结合.这解释了为什么没有被零除的原因。在连接之前应用此过滤器也很有意义,因为这可能会使连接操作涉及更少的记录。

关于MYSQL "Division by zero"警告,奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72955786/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com