MySql 5.7 UPDATE 和 DELETE 导致的 error code [1093]

13 篇文章 4 订阅
9 篇文章 0 订阅

错误信息

Error: 1093 SQLSTATE: HY000 (ER_UPDATE_TABLE_USED)

Message: You can’t specify target table ‘%s’ for update in FROM clause

在 MySql 中,由于安全原因,类似下面的 SQL 是无法执行的:

delete from table1 a where exists (
       select 1 from table1 b where a.id = b.oid)

这种 SQL 会报错:

[Err] 1093 - You can’t specify target table ‘table1’ for update in FROM clause

通常会采用类似下面的方式来避免这种错误:

delete from table1 a where exists (
       select 1 from (select * from table1) b where a.id = b.oid)

增加一层嵌套后,mysql 会当成临时表处理,这样就能避免上面的错误。

但是 5.7 版本的时候,其中一项优化会导致上面这种方式出错。

5.7.19 (或接近的版本)执行下面的 SQL:

EXPLAIN select * from (select * from mysql.user) t1

分析的结果如下:

1 SIMPLE user ALL 3 100

上面的 SQL 优化后就会变成下面这样:

select * from mysql.user

这就导致在上面 delete 中增加的一层嵌套被优化掉了,因此出现了 1093 的错误。

解决的办法就是在 UPDATE 和 DELETE 时,先执行下面的配置:

SET optimizer_switch = 'derived_merge=off';

这样就不会被优化合并了,使用这个配置后,解释上面的SQL结果如下:

1 PRIMARY ALL 3 100

2 DERIVED user ALL 3 100

如果想要针对全局配置可以使用下面的命令:

SET GLOBAL optimizer_switch = 'derived_merge=off';

如果想要数据库启动生效,还需要在my.ini(或my.conf)中的[mysqld]下面添加配置:

optimizer_switch = ‘derived_merge=off’

参考资料

derived_merge 说明:

https://dev.mysql.com/doc/refman/5.7/en/upgrading-from-previous-series.html

优化:

https://dev.mysql.com/doc/refman/5.7/en/derived-table-optimization.html

参数信息:

https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_optimizer_switch

错误信息:

https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_update_table_used

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

isea533

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值