微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

来自 5.7 的 mysql 8 查询回归有什么问题?

如何解决来自 5.7 的 mysql 8 查询回归有什么问题?

5.7 中的查询在 8.0.23 中不再有效。 针对 windows 8.0.23 x64 和 linux docker 容器 8.0.23 进行测试。

当前sql模式: ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_ENGINE_SUBSTITUTION

这不是最聪明的 sql,但这不是重点。

TL;DR: 关键是“bob”行应该在最后一个查询显示(如在 5.7 中),但在 8 中不再显示

详情:

在 4 个表设置和插入后,查询会逐步构建,并使用之前的查询来证明错误。最里面的 select 应该什么也没找到。中间选择只是重复。最后一个查询将 uu 连接到那个 'nothing',哦,惊奇的是,什么都没有! (它在最外面的 where 子句中失败了。

问题:

发生了什么变化?我们做错了什么?我们在 5.7 中假设的哪些不再正确?还是bug?

数据:

drop table if exists uu,ww,kk,aa;
CREATE TABLE uu (
  id int NOT NULL AUTO_INCREMENT,name varchar(30),PRIMARY KEY (`id`)
);
CREATE TABLE ww (
  id int NOT NULL,PRIMARY KEY (`id`)
);
CREATE TABLE kk (
  id int NOT NULL AUTO_INCREMENT,uid int,wid int,state int,PRIMARY KEY (`id`),CONSTRAINT `kk_uid` FOREIGN KEY (uid) REFERENCES uu (id),CONSTRAINT `kk_wid` FOREIGN KEY (wid) REFERENCES ww (id)
);
CREATE TABLE aa (
  id int NOT NULL AUTO_INCREMENT,CONSTRAINT `aa_uid` FOREIGN KEY (uid) REFERENCES uu (id),CONSTRAINT `aa_wid` FOREIGN KEY (wid) REFERENCES ww (id)
);
 
insert into uu (name) values ('alice'),('bob'),('chuck');
insert into ww (id) values (10),(11);
insert into kk (uid,wid,state) values (2,10,99);
insert into kk (uid,11,99);
insert into aa (uid,wid) values (2,10),(2,11);
 
-- plain joins:
select u.*,"][",k.*,a.*
     from uu u
    left join kk k on k.uid = u.id
    left join aa a on u.id = a.uid
    order by u.id,k.id;
 
select a2.*,'][',k3.* -- distinct a2.wid
                                     from aa a2
                                     left join kk k3 on a2.uid = k3.uid and a2.wid = k3.wid
                                     where k3.wid is null
;
SELECT a.*
                     FROM aa a
                     where a.wid in
                           (
                                select distinct a2.wid
                                     from aa a2
                                     left join kk k3 on a2.uid = k3.uid and a2.wid = k3.wid
                                     where k3.wid is null
                           )
;
 
select u.*,'][k','][k1',k1.*,'][tmp',tmp.*
     FROM uu u
    LEFT JOIN kk k ON k.uid = u.id
    LEFT JOIN kk k1 ON k1.uid = u.id AND k1.state != 99
    LEFT JOIN
           (
                SELECT a.*
                     FROM aa a
                     where a.wid in
                           (
                                select distinct a2.wid
                                     from aa a2
                                     left join kk k3 on a2.uid = k3.uid and a2.wid = k3.wid
                                     where k3.wid is null
                           )
           ) tmp ON tmp.uid = u.id
-- ;
   WHERE tmp.wid IS NULL
           AND (
                k.uid IS NULL
                OR
            (k.state = 99 AND k1.id IS NULL)
           )
;

解决方法

这绝对是一个错误。好像是在 8.0.17 引入的。

请在 bugs.mysql.com 上报告或告诉我,我会输入。

一种解决方法是设置这些优化器开关,如下所示:

set optimizer_switch='materialization=off';
set optimizer_switch='derived_merge=on';

感谢您使用 MySQL。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?