什么情况下,下列语句会输出 t1_view 总行数?
select count(*) from t1_view where id not in (select id from t1_view);
以下为操作:
create table t1 (id int primary key);
create table t2 (id int primary key);
insert t1 values (1),(2),(3);
insert t2 values (1);
create view t1_view as select a.id from t1 a join t2 order by a.id;
MariaDB [tmp]> select count(*) from t1_view where id not in (select id from t1_view);
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
MariaDB [tmp]> select count(*) from t1_view a where not exists (select id from t1_view b where a.id=b.id);
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
当前用 not exists 结果合理,但在一些情况下也有问题.
MariaDB [tmp]> select count(*) from t1_view a where not exists (select id from t1 b where a.id=b.id);
+----------+
| count(*) |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
不知道是什么情况,现在很混乱. 希望懂的人解释一下原因.
版本 10.1.29-MariaDB-6+b1 Debian buildd-unstable
1
choury 2018-08-26 20:25:42 +08:00 via Android
说了这么多没用的……你直接 select * from t1_view 就怎知道了
|
2
sycxyc OP @choury 你用手机所以可能不太清楚情况. t1 和 t1_view 数据是是一样的, 但结果应该都是 0. 实际程序比这个复杂很多, 复现条件是视图中至少要使用 join 和 order by, 我是很难再简化了.
|
3
choury 2018-08-26 20:47:28 +08:00
|
4
sycxyc OP |
5
msg7086 2018-08-27 07:30:06 +08:00
|
6
sycxyc OP @msg7086 不支持应该会报错,例如下面这种
MariaDB [tmp]> select * from t1_view c where c.id not in (select id from t1 limit 1); ERROR 1235 (42000): This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' 我认为是 mysql 优化器对视图支持存在缺陷, 目前发现新版本可以 set @@optimizer_switch='materialization=off'; 关闭后对 not exists 的结果会有所改善 禁用优化的另一种方法是,条件不要"简单直接" select count(*) from t1_view where 0+id not in (select id from t1_view); |
7
blodside 2018-08-27 13:11:50 +08:00
实际上我用 mysql 8.0.12 复现不出来这个问题,也就是例子里这几个 count 都是 0。
|
8
sycxyc OP |
9
msg7086 2018-08-27 14:01:21 +08:00
|
10
sycxyc OP |