前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL- In 和 Exists的优化案例讲解

MySQL- In 和 Exists的优化案例讲解

作者头像
小小工匠
发布2021-08-17 15:41:08
7040
发布2021-08-17 15:41:08
举报
文章被收录于专栏:小工匠聊架构

在这里插入图片描述
在这里插入图片描述


Demo Table

代码语言:javascript
复制
CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

create table t2 like t1;

两个表 t1 和 t2 , 一样的,包括索引信息

数据量 t1 ,t2 如下

代码语言:javascript
复制
mysql> select count(1) from t1;
+----------+
| count(1) |
+----------+
|    10000 |
+----------+
1 row in set

mysql> select count(1) from t2;
+----------+
| count(1) |
+----------+
|      100 |
+----------+
1 row in set

mysql> 

in的逻辑

代码语言:javascript
复制
select * from t1 where id in (select id from t2) ;

这个SQL,先执行哪个呢?

看看执行计划

在这里插入图片描述
在这里插入图片描述

可以理解为

代码语言:javascript
复制
for(select id from t2){
      select * from t1 where t1.id = t2.id
    }

优化原则

原则:小表驱动大表,即小的数据集驱动大的数据集

当T2表的数据集小于T1表的数据集时,in优于exists


exists的逻辑

代码语言:javascript
复制
select * from A where exists (select 1 from B where B.id = A.id)

可以理解为

代码语言:javascript
复制
  for(select * from A){
     select * from B where B.id = A.id
   }

当A表的数据集小于B表的数据集时,exists优于in

将主查询A的数据,放到子查询B中做条件验证,根据验证结果(true或false)来决定主查询的数据是否保留

  1. EXISTS (subquery)只返回TRUE或FALSE,因此子查询中的SELECT * 也可以用SELECT 1替换,官方说法是实际执行时会忽略SELECT清单,因此没有区别
  2. EXISTS子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比
  3. EXISTS子查询往往也可以用JOIN来代替,何种最优需要具体问题具体分析
代码语言:javascript
复制
mysql> explain select * from t2 where exists (select 1 from t1 where t1.id = t2.id) ;
+----+--------------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
| id | select_type        | table | partitions | type   | possible_keys | key     | key_len | ref           | rows | filtered | Extra       |
+----+--------------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
|  1 | PRIMARY            | t2    | NULL       | ALL    | NULL          | NULL    | NULL    | NULL          |  100 |      100 | Using where |
|  2 | DEPENDENT SUBQUERY | t1    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | artisan.t2.id |    1 |      100 | Using index |
+----+--------------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
2 rows in set
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/08/08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Demo Table
  • in的逻辑
    • 优化原则
    • exists的逻辑
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档