MySQL进阶
01、MySQL进阶:剖析MySQL索引底层数据结构
02、MySQL进阶:MySQL不同存储引擎下索引的实现
03、MySQL进阶:Explain深度剖析
04、MySQL进阶:践行索引优化
05、MySQL进阶:锁等待及死锁初探
06、MySQL进阶:无索引行锁升级为表锁
07、MySQL进阶:共享锁和排它锁初探
08、MySQL进阶:索引优化案例实操
09、MySQL进阶:索引下推IndexConditionPushdown初探
10、MySQL进阶:使用trace工具来窥探MySQL是如何选择执行计划的
11、MySQL进阶:orderby和groupby优化初探
12、MySQL进阶:分页查询优化的两个案例解析
13、MySQL进阶:Join关联查询优化
14、MySQL进阶:In和Exists的优化案例讲解
15、MySQL进阶:存储引擎初探
16、MySQL进阶:体系结构初探
17、MySQL进阶:解读MySQL事务与锁机制
18、MySQL进阶:多版本控制MVCC机制初探
19、MySQL进阶:并发事务问题及解决方案
20、MySQL进阶:锁机制初探
21、MySQL进阶:高效的设计MySQL库表
22、MySQL进阶:库表设计之IP和TIMESTAMP的处理
23、MySQL进阶:orderby出现usingfilesort根因分析及优化
24、MySQL进阶:canal实现mysql数据同步到redis|实现自定义canal客户端
本文档使用 MrDoc 发布
-
+
首页
14、MySQL进阶:In和Exists的优化案例讲解
 ------------ ### **Demo Table** ```python 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 如下 ```python 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的逻辑** ```python select * from t1 where id in (select id from t2) ; ``` 这个SQL,先执行哪个呢? 看看执行计划  可以理解为 ```python for(select id from t2){ select * from t1 where t1.id = t2.id } ``` ### **优化原则** 原则:小表驱动大表,即小的数据集驱动大的数据集 当T2表的数据集小于T1表的数据集时,in优于exists ------------ ### **exists的逻辑** ```python select * from A where exists (select 1 from B where B.id = A.id) ``` 可以理解为 ```python 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*也可以用SELECT1替换,官方说法是实际执行时会忽略SELECT清单,因此没有区别; 2、 EXISTS子查询的实际执行过程可能经过了优化而不是我们理解上的逐条对比; 3、 EXISTS子查询往往也可以用JOIN来代替,何种最优需要具体问题具体分析; ```python 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 ```
李智
2025年3月17日 13:32
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码