MySQL中EXITS语句用于查明表中是否存在特定的行。普遍情况下EXITS与子查询一起使用,并返回与子查询返回的结果相等或匹配的行。如果行在表中存在,则返回true,否则返回false。在MySQL中使用EXISTS是低效的,因为EXISTS对查理表中的每一行都要重新运行。

1. 常用方式

通过例子,了解EXISTS返回的两种情况:TRUE(1), FLASE(0)

mysql> CREATE TABLE students(id int PRIMARY KEY,firstName varchar(255) DEFAULT NULL,lastName varchar(255) DEFAULT NULL
);
INSERT INTO students(id,firstName,lastName) VALUES(1,"Preet","Sanghavi"), (2,"Rich","John"), (3,"Veron","Brow"), (4,"Geo","Jos"), (5,"Hash","Shah"), (6,"Sachin","Parker"), (7,"David","Miller");mysql> SELECT *FROM STUDENTS;
+----+-----------+----------+
| id | firstName | lastName |
+----+-----------+----------+
|  1 | Preet     | Sanghavi |
|  2 | Rich      | John     |
|  3 | Veron     | Brow     |
|  4 | Geo       | Jos      |
|  5 | Hash      | Shah     |
|  6 | Sachin    | Parker   |
|  7 | David     | Miller   |
+----+-----------+----------+
7 rows in set (0.00 sec)#查询id
mysql> SELECT EXISTS(SELECT * from students WHERE id=4) as RESULT;
+--------+
| RESULT |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)#查询不存在数据
mysql> SELECT EXISTS(SELECT * from students WHERE id=11) as RESULT;
+--------+
| RESULT |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)#执行计划
mysql> EXPLAIN SELECT EXISTS(SELECT * from students WHERE id=4) as RESULT;
+----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+----------------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra          |
+----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+----------------+
|  1 | PRIMARY     | NULL     | NULL       | NULL  | NULL          | NULL    | NULL    | NULL  | NULL |     NULL | No tables used |
|  2 | SUBQUERY    | students | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | Using index    |
+----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+----------------+

2.往往容易误写用法

没有条件限制,扫描所有行,最终结果只返回一条TRUE(1),不管是不是NULL

mysql > SELECT EXISTS(SELECT * from students ) as RESULT;
+--------+
| RESULT |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)
CREATE TABLE `course` (`id` int unsigned NOT NULL AUTO_INCREMENT,`stu_id` int NOT NULL,`course_name` varchar(20)  NOT NULL,`st_couse` int NOT NULL,PRIMARY KEY (`id`),KEY `idx_stu` (`stu_id`)
);
INSERT INTO  course(stu_id,course_name,st_couse) VALUES(1,'语文',98),(2,'数学',89),(3,'英语',92);mysql> SELECT st.* FROM students stWHERE EXISTS (SELECT cs.stu_id FROM course cs  );
+----+-----------+----------+------+
| id | firstName | lastName | age  |
+----+-----------+----------+------+
|  1 | Preet     | Sanghavi | NULL |
|  2 | Rich      | John     | NULL |
|  3 | Veron     | Brow     | NULL |
|  4 | Geo       | Jos      | NULL |
|  5 | Hash      | Shah     | NULL |
|  6 | Sachin    | Parker   | NULL |
|  7 | David     | Miller   | NULL |
+----+-----------+----------+------+
7 rows in set (0.00 sec)mysql> SELECT st.* FROM students stWHERE EXISTS (SELECT cs.stu_id FROM course cs WHERE cs.stu_id = st.id  );
+----+-----------+----------+------+
| id | firstName | lastName | age  |
+----+-----------+----------+------+
|  1 | Preet     | Sanghavi | NULL |
|  2 | Rich      | John     | NULL |
|  3 | Veron     | Brow     | NULL |
+----+-----------+----------+------+
3 rows in set (0.00 sec)

注意:两次查询结果不一样,仔细对比上面两条 sql 语句,where 语句后面直接跟了exists ,并没有指定关联条件。这里EXISTS 只在乎WHERE里的数据能不能查找出来,是否存在这样的记录。
其运行方式是先运行主查询一次,再去子查询里查询与其对应的结果 如果存在返回ture则输出,反之返回false则不输出,再根据主查询中的每一行去子查询里去查询。适合外查询表小,子查询表大的情况,毕竟要一行抽取进行匹配。

3.优化SQL语句

EXISTS是否可以改写进行优化,下面是改写成内连接方式:

mysql> SELECT st.* FROM students st  INNER JOIN course cs  ON   cs.stu_id = st.id ;

执行计划对比:

Semi Join-LooseScan: 把数据基于索引进行分组,取每组数据进行匹配

EXPLAIN ANAYLZE实际执行:

从上诉对比中可以看出,在少量的数据中也存在明显的差异。

4. DDL中EXISTS

在DDL语句创建或删除中添加EXISTS,还是有很多好处的。
如果没有IF EXISTS,语句将失败,并出现一个错误,表明无法删除哪些不存在的表,并且不会进行任何更改。

使用IF EXISTS时,对于不存在的表不会发生错误。该语句删除所有确实存在的已命名表,并为每个不存在的表生成一个NOTE诊断。这些注释可以通过SHOW WARNINGS显示

  • 如果在数据字典中有一个条目,但存储引擎没有管理表的特殊情况下,IF EXISTS也可以用于删除表。(例如,在从存储引擎中删除表之后,在删除数据字典条目之前,服务器异常退出。有一定的效果,但有时未必可行)
2021-11-24T11:33:54.885641Z 0 [ERROR] InnoDB: Cannot open datafile for read-only: './db9/t1.ibd' OS error: 71
2021-11-24T11:33:54.885645Z 0 [ERROR] InnoDB: Operating system error number 2 in a file operation.
2021-11-24T11:33:54.885648Z 0 [ERROR] InnoDB: The error means the system cannot find the path specified.
2021-11-24T11:33:54.885651Z 0 [ERROR] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.
2021-11-24T11:33:54.885656Z 0 [ERROR] InnoDB: Could not find a valid tablespace file for `db9/t1`. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.

EXIST删除操作:

mysql> DROP DATABASE db9;
ERROR 3679 (HY000): Schema directory './db9/' does not exist
mysql> DROP DATABASE IF EXISTS db9;
Query OK, 0 rows affected, 1 warning (0.03 sec)
  • EXIST 存储过程适用:

  • 与EXISTS相对的是NOT EXISTS。使用NOT EXISTS后,若对应查询结果为空,则外层的WHERE子语句返回值为真值,否则返回假值。

  • 在MySQL 8.0.19及以后版本中,也可以在子查询中使用NOT EXISTS或NOT EXISTS嵌套

4.总结

MySQL中EXISTS这些没有特殊的要求,主要考虑性能方面的问题。可以尽量用INNER JOIN。必须用到EXISTS时外查询表小,子查询表大原则,可以有效减少总的循环次数来提升速度。
有时DDL中系统突然宕机,可以用IF EXISTS进行处理也能启动妙用。

MySQL SQL语句EXISTS相关推荐

  1. mysql sql语句生成日历表

    转载:http://blog.csdn.net/u010363836/article/details/52788358 mysql sql语句生成日历点击打开链接表  (主要用于按月,按天group ...

  2. Mysql SQL语句执行更新或者插入添加条件判断

    Mysql SQL语句执行更新或者插入添加条件判断 – 更新操作 – INSERT INTO materials (ID,Name,Remaining,Total) VALUES (1,'SolidW ...

  3. 数据库Mysql——sql语句大全

    注意:练习sql语句之前推荐先安装可视化软件如:SQLyog.Navicat 15 for MySQL 不然就在cmd小黑窗口敲命令练习. 一篇掌握Mysql--sql语句 #注意:sql语句不区分大 ...

  4. 导出mysql sql语句吗_mysql sql语句导入与导出

    mysql sql语句导入与导出 导入: mysql -u root -p 数据库名 如: C:/mysql/bin>mysql -u root -p house < c:/1-1.txt ...

  5. MySQL sql语句获取当前日期|时间|时间戳

    文章转载于:博客园--水狼一族 文章地址:<MySQL sql语句获取当前日期|时间|时间戳> 一.基础时间函数 1.1 获得当前日期+时间(date + time)函数:now() My ...

  6. mysql sql语句执行顺序

    mysql sql语句执行顺序 引言:作为一个程序猿.要想优化sql,首先要明白sql语句的执行顺序.同时防止该死的面试官问一些数据库专业的问题有必要知道这些 sql语句select语句查询顺序 (7 ...

  7. mysql sql语句大全

    1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份 ...

  8. mysql sql语句 入门_mysql(3)mysql的sql语句入门

    1.登录mysql与退出mysql 登录:mysql  -u账号 -p密码 -h主机地址 -P端口号  -e 执行的sql语句: //密码一般不直接写出,回车后隐藏写入 ,-h可以不写默认是local ...

  9. MySQL - SQL语句增加字段/修改字段/修改类型/修改默认值

    1.应用场景 有时[比如在Linux服务器下]需要使用SQL语句直接对数据表进行新建/修改表结构, 填充/更新数据等. 或借助数据库管理工具执行SQL,但是这种方法,比较适合做微小的操作- 好处: 使 ...

最新文章

  1. python中函数的调用_慢步python,编程中函数的概念,python中函数的声明和调用
  2. # mergeSort 归并排序
  3. 想写一篇关于.net下COM工作原理的文章
  4. IOC--IOC+AOP--热插拔的系统架构实现演化
  5. oracle预定义异常
  6. 数据列表的分页实现————分页敏捷开发
  7. 图片圆角边框自适应宽高(深夜原创)
  8. [算法]复杂链表的复制
  9. dbf文件怎么创建_DBC文件到底是个啥
  10. 100行Python代码的贪吃蛇
  11. yum 安装Mysql8.0
  12. 【微信支付】小案例,Java版
  13. DXGI抓屏优化扩展:GPU硬件编码保存文件即录像为MP4和FLV,外加麦克风+计算机声音
  14. studio3t破解
  15. 正交矩阵和旋转矩阵之间关系和性质总结
  16. 让刷Q币者对爱机你无从下手
  17. Windows系统复制文件到虚拟机Linux环境的解决
  18. C++编程-腐烂的橘子-广度优先搜索
  19. uniapp开发h5微信授权登录(详细教程)
  20. Oracle Spatial中上载GIS空间数据方法研究

热门文章

  1. 【洛谷p1605】迷宫
  2. Docker 极简入门指南,10 分钟就能看懂~
  3. 谷歌广告代运营,谷歌广告代投
  4. 教你以普通本科生学历,拿大厂的offer!!!
  5. 关闭笔记本电脑的ScrollLock键
  6. 清华大学刘徐舟老师经典语录
  7. mysql5.7连接navicat?
  8. Java 设计模式 之 克隆模式
  9. 用户自定义短语跨平台同步(Mac-> Winodws)
  10. iPhone概念机终于被三星做出来了