当前位置: 首页 > news >正文

ipad做电影网站苏州制作网页公司

ipad做电影网站,苏州制作网页公司,搜索引擎优化的特点,wordpress 视频外链Mysql实战-SQL语句Join,exists,in的区别 前面我们讲解了索引的存储结构,BTree的索引结构,以及索引最左侧匹配原则及讲解一下常用的SQL语句的优化建议,今天我们来详细讲解一下 我们经常使用的 join, exist&…

Mysql实战-SQL语句Join,exists,in的区别

前面我们讲解了索引的存储结构,B+Tree的索引结构,以及索引最左侧匹配原则及讲解一下常用的SQL语句的优化建议,今天我们来详细讲解一下 我们经常使用的 join, exist, in三者的区别

文章目录

      • Mysql实战-SQL语句Join,exists,in的区别
        • 1.表结构
        • 2.使用 in查询 用户及订单表
        • 3.使用 exists查询 替换 in语句, 查询用户及订单表
        • 4. in exists 用法对比
        • 4. 加索引看下执行结果与not in, not exists对比

1.表结构

新建表结构 user, user_info

#新建表结构 user
CREATE TABLE `user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`id_card` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '身份证ID',`user_name` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名字',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'#新建订单表 order_info
CREATE TABLE `order_info` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`order_id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单ID',`user_name` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名字',`address` char(32)  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户地址',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表'

先插入测试数据, 插入 5条user 测试数据 2条订单数据

INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (1, '11', 'aa', 10);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (2, '22', 'bb', 20);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (3, '33', 'cc', 30);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (4, '44', 'dd', 40);
INSERT INTO `test`.`user` (`id`, `id_card`, `user_name`, `age`) VALUES (5, '55', 'ee', 50);#2条订单数据
INSERT INTO `test`.`order_info` (`id`, `order_id`, `user_name`, `address`) VALUES (1, '1', 'aa', '北京');
INSERT INTO `test`.`order_info` (`id`, `order_id`, `user_name`, `address`) VALUES (2, '2', 'bb', '上海');
2.使用 in查询 用户及订单表

我们查看下存在订单的用户有哪些?

select * from user where user_name in (select user_name from order_info );
explain select * from user where user_name in (select user_name from order_info )

我们看下Explain执行分析

  • in查询没有驱动表,先执行子查询,然后再执行外层表
  • in 子查询会 使用了临时表 Start Temporary
  • in查询其实把外表和内表 作hash 连接,Using join buffer (hash join) 使用hash 连接, 当子查询数量较多时,hash连接后的数据量特别大
  • order_info 表 type=ALL没有索引, user表也没有索引, type=ALL

在这里插入图片描述
查询结果: 2条数据,正确
在这里插入图片描述

3.使用 exists查询 替换 in语句, 查询用户及订单表

前面我们使用了in来进行查询, 现在我们使用 exists来替换 in,实现查询效果

select * from user where exists (select user_name from order_info  where user.user_name = order_info.user_name);
explain select * from user where exists (select user_name from order_info  where user.user_name = order_info.user_name);

我们看下Explain执行分析

  • Exists 同样也会使用临时表
  • 二者的连接同样也是 hash join
  • Exist是 外层表是驱动表, 先执行外层表,再执行内层表
  • 这样看起来似乎是没有区别的,下面我们专门对比下2者
    在这里插入图片描述
    查询结果2条数据,正确
    在这里插入图片描述
4. in exists 用法对比

前面我们尝试用 in 和 exists 来对比
我们都知道 如果涉及子查询的时候,我们都是小表驱动大表,先查小表,然后查大表,这就导致了in和exists用法的区别

  • in 先执行子查询,使用于内小,外大
  • exist 先执行外层表驱动表,适用于外小,内大
  • in适合 外层大, 内层小, 先执行内层子查询,过滤出来一小部分数据,再用来查外层
  • exist适用于外层小,内层大,先执行外层驱动表查询,出来一部分数据,再查内层表

简单通俗来讲就是下面的案例

如果 order表有1w数据,user表有10条数据, order是大表, user是小表, 采用 in 内小外大的用法

  • select * from order where user_name in ( select user_name from user )
  • in 子查询 user 是小表, 外层order 是大表

如果 user表有1w数据, order表有10条数据,上面的明显是错误的用法,采用 exists的 外小内大的用法

  • select * from order where exists (select user_name from user where user.user_name = order_info.user_name )
  • order 外小, user 内大
4. 加索引看下执行结果与not in, not exists对比

前面我们尝试用 in 和 exists 来对比,加上索引后,对比下 二者的结果
二者全部都使用了索引

alter table user add index idx_name(user_name);
alter table order_info add index idx_name(user_name);
explain select * from user where user_name in (select user_name from order_info )
explain select * from user where exists (select user_name from order_info  where user.user_name = order_info.user_name);
  • order_info 表 type=index, user表 type=ref,全都使用了索引
    在这里插入图片描述
    我们再尝试下 not in 和 not exists
explain select * from user where user_name not in (select user_name from order_info )
explain select * from user where not  exists (select user_name from order_info  where user.user_name = order_info.user_name);
  • not in 查询类型 select type 变成了 PRIMARY 和 DEPENDENT SUBQUERY
  • not in 索引 type类型变成了ALL 和index_subquery
  • not exists 查询类型 select type 依旧是 simple
  • not in 索引 type类型变成了ALL 和ref
    所以我们还是尽量不要用 not in ,not exists 这种SQL语法
    在这里插入图片描述

至此,我们彻底的了解了 in, exists的区别,下一篇我们讲解下 join的原理,通过join原理,我们可以更加了解SQL查询的底层逻辑

http://www.yayakq.cn/news/345371/

相关文章:

  • 夜间正能量不良网站入口不用下载价格低的形容词
  • 邯郸网站建设有哪些网站联系我们的地图怎么做
  • 中式建筑网站营销类网站
  • 视频网站直播怎么做的 百度一下
  • 威海网站制作都有哪些简述电子商务网站开发的研究意义
  • 静态网站开发工具手工活接单正规平台
  • 个人简历免费模板下载宁波专业seo推广价格
  • 我的网站突然找不到网页了wordpress模板制作兼职
  • 广东营销网站制作企业所得税税前扣除项目有哪些
  • 淘宝网站建设基本流程upyun for wordpress
  • 清远网站关键字优化小游戏链接点开即玩
  • 富阳有没有做网站的网站开发证有没有用
  • 网站建设实训经验总结山西建设局网站
  • 免费网站建设怎样wordpress 插件 code
  • 校园网站建设情况wordpress站点优化
  • 申请免费网站域名wordpress 农历小工具
  • 国外优秀网站欣赏网站建设相对应的税收分类是
  • 鞍山做网站团队网页设计欣赏熊出没
  • espcms易思企业网站wordpress3.7
  • 途牛旅游网站建设背景directadmin wordpress
  • 网站建设的主要技术路线产品营销文案
  • 公司是做网站建设的怎么开票全国网站建设排名
  • 做网站哪个编辑器好用哪些是 joomla做的网站
  • 昆山专业做网站备案变更网站
  • 电脑公司网站源码茶叶网站的建设策划书
  • 什么是sem推广东莞关键词seo
  • 网站优化收费途牛旅游网
  • 邢台市做网站电话wordpress与php
  • 做海报素材的网站三亚百度推广公司电话
  • 许昌哪个网站做苗木响应式网站建设哪家公司好