我正在使用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是一种declarative语言,所以您可以指定what而不是how:这留给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))"

这清楚地表明,在col1<>0之前判断col2/col1>0

然后,我对上述表运行了以下查询:

SELECT *
FROM Test T JOIN Test1 T1 ON T.col2=T1.colA
WHERE  T.col2/T.col1>0 AND T.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)

首先执行内部动作.在这里,我们看到来自T的记录首先被T.col1 <> 0过滤,然后才与来自T1的记录合并.这解释了为什么不发生零除.将该过滤器应用于连接也是有意义的,因为这可能会使连接操作涉及更少的记录.

Mysql相关问答推荐

将值代入子查询

用于将重复行的唯一列值作为单独列获取的SQL查询

基于多行从表中 Select

使用不同的 where 列进行子 Select

根据名称将值从一个字段复制到不同记录的同一字段

使用适配器设计模式和外观设计模式实现

如何将结果列中的不同值按其他列sql中的值带入单行

MySQL - 单词边界的正则表达式,不包括下划线(连接标点符号)

SQL从字典中的键获取值

进行 MySQL COUNT 查询

插入重复键查询以在每一行上进行自定义更新

MYSQL 或 Laravel Eloquent 如何从这个订单中统计细节

如何查询打印已售罄的产品? [MYSQL]

SQL 查找边界之间的值

MySQL - 计算行重复的最大计数

计算每个用户在第二个表中有多少条记录

使用case查询并更新最后一条记录

不正确的整数(2147483647)被插入到 MySQL 中?

MySQL如何为数据库中的所有表生成DDL

MySQL - 基于同一表中的行求和列值