今天在浏览墨天轮社区时,看到一篇文章 https://www.modb.pro/db/1788830043766067200?utm_source=index_hot ,借用一下文中的例子如下所示:
/* table1 */
create table enmotech (id number,name varchar2(20));
insert into enmotech values(1,'Eygle');
/* table2 */
create table enmotest (id number);
insert into enmotest values(1);
/* 问:在enmotest 表中,不存在 name 字段,当前查询能否正常执行?*/
select * from enmotech where name in (select name from enmotest);
思考一下能否正确执行,如果能,那么输出结果是什么?
我们先在SQLSERVER上运行一下看一下,
在Greatsql运行一下,看一下。
在PG上运行一下看一下。
在ORACLE运行一下看一下
explain select * from enmotech where name in (select name from enmotest);
+----+-------------+----------+------------+------+---------------+------+---------+--- ---+------+----------+-----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | re f | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+--- ---+------+----------+-----------------------------------------------------+
| 1 | SIMPLE | enmotech | NULL | ALL | NULL | NULL | NULL | NU LL | 1 | 100.00 | Using where |
| 1 | SIMPLE | enmotest | NULL | ALL | NULL | NULL | NULL | NU LL | 1 | 100.00 | FirstMatch(enmotech); Using join buffer (hash join) |
+----+-------------+----------+------------+------+---------------+------+---------+--- ---+------+----------+-----------------------------------------------------+
2 rows in set, 2 warnings (0.01 sec)
从上图上执行计划看,使用了Greatsql的FirstMatch,从逻辑上看,上面的语句是不可能执行的,但实际上却执行了。
explain verbose select * from enmotech where name in (select name from enmotest) ;
QUERY PLAN
----------------------------------------------------------------------------
Seq Scan on public.enmotech (cost=0.00..9333.62 rows=345 width=90)
Output: enmotech.id, enmotech.name
Filter: (SubPlan 1)
SubPlan 1
-> Seq Scan on public.enmotest (cost=0.00..23.60 rows=1360 width=58)
Output: enmotech.name
(6 rows)
以上是PG的执行计划,可以清楚看到。子查询也就是子计划实际上输出的enmotech.name。