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

数据库的基础的exists

很多基础的东西可以拿来细说一下:

假设X和Y两个表如下:
mysql> select * from x;
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
|  4 |    4 |
|  5 |    5 |
|  6 |    6 |
|  7 |    7 |
|  8 |    8 |
|  9 |    9 |
| 10 |   10 |
+----+------+
10 rows in set (0.00 sec)

mysql> select * from y;
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
3 rows in set (0.00 sec)

如果写成exists那么,这两种是一样的结果。由于Y表只有3行数据库。X表也只有10条。不会有性能问题。 

实际上这样写,子查询有一条或者是1万条都是 只看1条。仅做一次判断。然后就执行父查询,几乎没有差别。

mysql> select * from x where exists (select *from y where y.id=1);
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
|  4 |    4 |
|  5 |    5 |
|  6 |    6 |
|  7 |    7 |
|  8 |    8 |
|  9 |    9 |
| 10 |   10 |
+----+------+
10 rows in set (0.00 sec)

mysql> select * from x where exists (select *from y);
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
|  4 |    4 |
|  5 |    5 |
|  6 |    6 |
|  7 |    7 |
|  8 |    8 |
|  9 |    9 |
| 10 |   10 |
+----+------+
10 rows in set (0.00 sec)

而实际工作中X和表Y表都会很大。而且实际工作中更多的是下面这种写法。这种关联子查询的方式。

我见到的多是下面这种。开发就写成这样了。我一直觉得这其实属于数据库表设计问题。

那么这种就是返回了较少的表的全部数据。当然这种会随着两个表的数量上升以及关联的范围越来越大会变得越来越慢。

真实的情况是两个表结果集都很大。不可能只有3条数据的。当然这就和exists本身关系不大了。那就两个表直接关联好了。

失去了exists的意义。

mysql> select * from x where exists (select *from y where x.id=y.id);
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
3 rows in set (0.00 sec)


有时候这个较少的表也很大。比如这时候子查询是2条。而实际情况子查询可能200万或者是2000万。
mysql> select * from x where exists (select *from y where x.id=y.id and y.id>1);
+----+------+
| id | a    |
+----+------+
|  2 |    2 |
|  3 |    3 |
+----+------+
2 rows in set (0.00 sec)


从日志中就可以看到,关联子查询不会再是子查询仅返回1行的那种优势了。随着结果集的变化而变化。

# Query_time: 0.000857  Lock_time: 0.000012 Rows_sent: 3  Rows_examined: 6
select * from x where exists (select *from y where x.id=y.id);

# Query_time: 0.001061  Lock_time: 0.000014 Rows_sent: 2  Rows_examined: 5
select * from x where exists (select *from y where x.id=y.id and y.id>1);


以上都有一些等价改写,不过我还是建议从设计出发来解决。

其实日常工作中遇到的都是基础问题,很难有什么高级问题。关注一下基础吧。

我的新书中有更多有价值的的经验。

《DBA实战手记》--薛晓刚     京东预售中。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • java中字面量和golang中字面量区别
  • 掌握Java并发编程基础
  • 计算机网络(网络层)
  • 基于RFID技术的智能压缩机装配线优化方案
  • 2024年有哪些好用的文件加密软件?十款常用加密软件推荐
  • Docker 环境下使用 Traefik v3 和 MinIO 快速搭建私有化对象存储服务
  • Ubuntu 22.04 Docker安装笔记
  • python3 pyside6图形库学习笔记及实践(四)
  • 社交巨头与去中心化:解析Facebook在区块链的角色
  • 记录|LabVIEW从0开始【09~10】
  • 操作系统(信号处理)
  • 新160个crackme - 023-TraceMe
  • Rabbitmq中的死信队列
  • 【时时三省】(C语言基础)二维数组
  • 【爬虫实战】利用代理爬取Temu电商数据
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【附node操作实例】redis简明入门系列—字符串类型
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • es6--symbol
  • extjs4学习之配置
  • github指令
  • JavaScript学习总结——原型
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • select2 取值 遍历 设置默认值
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 世界上最简单的无等待算法(getAndIncrement)
  • 收藏好这篇,别再只说“数据劫持”了
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 学习ES6 变量的解构赋值
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 用jQuery怎么做到前后端分离
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • 进程与线程(三)——进程/线程间通信
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​ubuntu下安装kvm虚拟机
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • !$boo在php中什么意思,php前戏
  • #1014 : Trie树
  • #NOIP 2014# day.2 T2 寻找道路
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (10)STL算法之搜索(二) 二分查找
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (超详细)语音信号处理之特征提取
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (四)进入MySQL 【事务】
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表