EXCEPT/MINUS

EXCEPT 算子用于对左右子节点算子输出集合进行差集运算,并进行去重。

Oracle 模式下一般使用 MINUS 进行差集运算,MySQL 模式下一般使用 EXCEPT 进行差集运算。OceanBase 数据库的 MySQL 模式不区分 EXCEPTMINUS,两者均可作为差集运算关键字使用。

OceanBase 数据库支持的 EXCEPT 算子包括 MERGE EXCEPT DISTINCTHASH EXCEPT DISTINCT

MERGE EXCEPT DISTINCT

如下示例中,Q1 对两个查询使用 MINUS 进行联接, c1 列有可用排序,0 号算子生成了 MERGE EXCEPT DISTINCT 进行求取差集、去重,由于 c2 列无可用排序,所以在 3 号算子上分配了 SORT 算子进行排序。算子执行时从左右子节点读取有序输入,利用有序输入进行 MERGE, 实现去重并得到差集结果。

obclient>CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT);
Query OK, 0 rows affected (0.12 sec)

obclient>INSERT INTO t1 VALUES(1,1);
Query OK, 1 rows affected (0.12 sec)

obclient>INSERT INTO t1 VALUES(2,2);
Query OK, 1 rows affected (0.12 sec)

Q1: 
obclient>EXPLAIN SELECT c1 FROM t1 MINUS SELECT c2 FROM t1\G;
*************************** 1. row ***************************
Query Plan:
==============================================
|ID|OPERATOR             |NAME|EST. ROWS|COST|
----------------------------------------------
|0 |MERGE EXCEPT DISTINCT|    |2        |77  |
|1 | TABLE SCAN          |T1  |2        |37  |
|2 | SORT                |    |2        |39  |
|3 |  TABLE SCAN         |T1  |2        |37  |
==============================================
Outputs & filters: 
-------------------------------------
  0 - output([MINUS(T1.C1, T1.C2)]), filter(nil)
  1 - output([T1.C1]), filter(nil), 
      access([T1.C1]), partitions(p0)
  2 - output([T1.C2]), filter(nil), sort_keys([T1.C2, ASC])
  3 - output([T1.C2]), filter(nil), 
      access([T1.C2]), partitions(p0)

上述示例中,执行计划展示中的 outputs & filters 详细列出了 EXCEPT 算子的输出信息如下:

信息名称

含义

output

该算子的输出表达式。

使用 EXCEPT/MINUS 联接的两个子节点算子对应输出(Oracle 模式使用 MINUS,MySQL 模式使用 EXCEPT),表示差集运算输出结果中的一列,括号内部为左右子节点对应此列的输出列。

filter

该算子上的过滤条件。

由于示例中 EXCEPT 算子没有设置 filter,所以为 nil

HASH EXCEPT DISTINCT

如下示例中,Q2 对两个查询使用 MINUS 进行联接,不可利用排序,0 号算子使用 HASH EXCEPT DISTINCT 进行求取差集、去重。算子执行时先读取左侧子节点输出建立哈希表并去重,再读取右侧子节点输出利用哈希表求取差集并去重。

Q2: 
obclient>EXPLAIN SELECT c2 FROM t1 MINUS SELECT c2 FROM t1\G;
*************************** 1. row ***************************
Query Plan:
=============================================
|ID|OPERATOR            |NAME|EST. ROWS|COST|
---------------------------------------------
|0 |HASH EXCEPT DISTINCT|    |2        |77  |
|1 | TABLE SCAN         |T1  |2        |37  |
|2 | TABLE SCAN         |T1  |2        |37  |
=============================================
Outputs & filters: 
-------------------------------------
  0 - output([MINUS(T1.C2, T1.C2)]), filter(nil)
  1 - output([T1.C2]), filter(nil), 
      access([T1.C2]), partitions(p0)
  2 - output([T1.C2]), filter(nil), 
      access([T1.C2]), partitions(p0)

上述示例的执行计划展示中的 outputs & filters 详细列出了 HASH EXCEPT DISTINCT 算子的输出信息,字段的含义与 MERGE EXCEPT DISTINCT 算子相同。