mysql中delete in子查询不走索引问题分析


推荐学习:mysql视频教程

文章开篇前,先问大家一个问题:delete in子查询,是否会走索引呢?很多伙伴第一感觉就是:会走索引。最近我们有个生产问题,就跟它有关。本文将跟大家一起探讨这个问题,并附上优化方案。

问题复现

MySQL版本是5.7,假设当前有两张表accountold_account,表结构如下:

CREATE TABLE `old_account` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
  `name` varchar(255) DEFAULT NULL COMMENT '账户名',
  `balance` int(11) DEFAULT NULL COMMENT '余额',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='老的账户表';
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',
  `name` varchar(255) DEFAULT NULL COMMENT '账户名',
  `balance` int(11) DEFAULT NULL COMMENT '余额',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';

执行的SQL如下:

delete from account where name in (select name from old_account);

我们explain执行计划走一波,

explain结果可以发现:先全表扫描 account,然后逐行执行子查询判断条件是否满足;显然,这个执行计划和我们预期不符合,因为并没有走索引

但是如果把delete换成select,就会走索引。如下:

为什么select in子查询会走索引,delete in子查询却不会走索引呢?

原因分析

select in子查询语句跟delete in子查询语句的不同点到底在哪里呢?

我们执行以下SQL看看

explain select * from account where name in (select name from old_account);
show WARNINGS;
show WARNINGS 可以查看优化后,最终执行的sql

结果如下:

select `test2`.`account`.`id` AS `id`,`test2`.`account`.`name` AS `name`,`test2`.`account`.`balance` AS `balance`,`test2`.`account`.`create_time` AS `create_time`,`test2`.`account`.`update_time` AS `update_time` from `test2`.`account` 
semi join (`test2`.`old_account`)
where (`test2`.`account`.`name` = `test2`.`old_account`.`name`)

可以发现,实际执行的时候,MySQL对select in子查询做了优化,把子查询改成join的方式,所以可以走索引。但是很遗憾,对于delete in子查询,MySQL却没有对它做这个优化。

一览妙笔 一览妙笔

自媒体、编剧、营销人员写作工具

一览妙笔 50 查看详情 一览妙笔

优化方案

那如何优化这个问题呢?通过上面的分析,显然可以把delete in子查询改为join的方式。我们改为join的方式后,再explain看下:

可以发现,改用join的方式是可以走索引的,完美解决了这个问题。

实际上,对于update或者delete子查询的语句,MySQL官网也是推荐join的方式优化

其实呢,给表加别名,也可以解决这个问题哦,如下:

explain delete a from account as a where a.name in (select name from old_account)

为什么加个别名就可以走索引了呢?

what?为啥加个别名,delete in子查询又行了,又走索引了?

我们回过头来看看explain的执行计划,可以发现Extra那一栏,有个LooseScan

LooseScan是什么呢? 其实它是一种策略,是semi join子查询的一种执行策略。

因为子查询改为join,是可以让delete in子查询走索引;加别名呢,会走LooseScan策略,而LooseScan策略,本质上就是semi join子查询的一种执行策略。

因此,加别名就可以让delete in子查询走索引啦!

推荐学习:mysql视频教程

以上就是mysql中delete in子查询不走索引问题分析的详细内容,更多请关注其它相关文章!


# 它是  # 网站优化排名方法及步骤  # 昌乐网站推广产品  # 图木舒克网站优化排名  # seo快速刷烹饪等级  # 自己如何在网站做推广  # 汇源果汁网站推广图片  # 品牌型网站推广  # 福田网站优化排名公司  # 网站建设得去林洁信赖  # 泉州网站优化常识  # mysql  # 就会  # 如何设置  # 主键  # 就可以  # 有个  # 更新时间  # 这个问题  # 不走  # 镜像 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: Win10如何彻底关闭OneDrive Win10禁用云同步功能【纯净】  《暗黑破坏神4》国服回归送狂欢礼包 价值6916元  如何查询个人病历记录  人教版电子教材在线获取指南  疯狂小鸟微信小游戏入口 疯狂小鸟网页版秒玩  mysql怎么导入sql文件_mysql导入sql文件的方法与技巧  如何配置VS Code作为您Git操作的默认编辑器  C++ cast类型转换总结_C++ reinterpret_cast与const_cast的使用  使用Selenium在无头Chrome中交互动态菜单和复选框的策略  批改网官网首页登录 批改网学生用户登录入口  Python类装饰器动态修改方法时的类型提示:Mypy插件实现精确静态分析  深入理解J*aScript异步操作:setTimeout与调用栈的真相  《雷电模拟器》自动点击设置方法  Windows自带的便笺数据如何备份_防止数据丢失的便利贴迁移教程【干货】  路由器DNS怎么设置最快 优化DNS提升上网速度教程  mail.qq.com登录入口 QQ邮箱网页版直达  被称为海蜈蚣的海洋动物是  QQ网站入口直接登录 QQ官方正版登录页面  163邮箱登录入口官网 163.com邮箱登录入口  抄漫画官网防走失地址_抄漫画最新漫画完整版阅读入口  J*aScript模块加载器_RequireJS原理分析  解决C#跨线程访问XML对象的异常 安全的并发XML处理模式  如何查询国外邮政编码_国外邮政编码查询的多种有效途径  猫眼app抢票快还是小程序快  抖音赚钱快速入门_新手必看的抖音赚钱步骤  《大周列国志》皇帝律令功能介绍  漫蛙manwa漫画官网链接_漫蛙manwa最新可用网址推荐  国际经济与贸易就业方向解析  在Django单元测试中优雅处理信号:基于环境的条件执行策略  铁拳8在线玩 铁拳8在线秒玩入口  哔哩哔哩黑名单怎么查看  VS Code如何设置默认配置  j*a中ArrayBlockingQueue的使用  顺丰快递在线查询系统 顺丰快递官方查单入口  抖音官网入口快速访问 抖音网页版账号注册解析  抖音手机分身两个账号怎么切换?分身两个系统是一样的吗?  Composer如何使用composer-plugin-api开发自定义插件  c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化  利用Flexbox实现图片元素的二维布局:2x2网格排列指南  自定义你的VS Code状态栏,监控关键信息  泰拉瑞亚网页版在线登录入口 泰拉瑞亚官方正版入口  QQ网页版官方账号登录入口 QQ网页版网页版入口快速导航  WPS文字如何进行简繁转换  基于 Flink 和 Kafka 实现高效流处理:连续查询与时间窗口  J*aScript大数运算_BigInt使用指南  电脑双系统如何安装和卸载 Windows和Linux双系统安装教程【详解】  QQ邮箱手机版网页版 QQ邮箱登录入口地址  海棠阅读网页版_进入海棠网页版在线阅读中心  Dash应用中自定义HTML页面标题与网站图标(F*icon)的实用指南  腾讯QQ邮箱官方入口 QQ邮箱网页版登录平台 

 2022-09-08

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.