ITPub博客

首页 > 数据库 > 数据库开发技术 > 数据库的基础的exists

数据库的基础的exists

原创 数据库开发技术 作者:xuexiaogang 时间:2024-08-05 21:34:27 0 删除 编辑

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


假设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实战手记》--薛晓刚     京东预售中。







来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/637517/viewspace-3024240/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: in null和not in null
请登录后发表评论 登录
全部评论
OracleACE/PostgreSQLACE/阿里云MVP/腾讯云TVP/墨天轮 MVP/TiDBMVA/数盟会华东区长老/OpenTenBase社区委和技术委委员/架构师技术同盟名人堂成员上海地区理事会成员/if社区联合发起人/《DBA实战手记》作者/公众号:四海内皆兄弟

注册时间:2013-07-01

  • 博文量
    422
  • 访问量
    953269