暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

OceanBase管理数据库执行计划算子COUNT

2023-05-31
438

COUNT 算子用于兼容 Oracle 的 ROWNUM 功能,实现 ROWNUM 表达式的自增操作。

说明

COUNT 算子为 OceanBase 数据库 Oracle 模式下独有。

在一般场景下,当 SQL 查询含有 ROWNUM 时,SQL 优化器就会在生成执行计划的时候分配一个 COUNT 算子。当然在一些情况下,SQL 优化器会将含有 ROWNUM 的 SQL 改写为 LIMIT 算子,这时就不会再分配 COUNT 算子。

说明

COUNT 算子为 OceanBase 数据库 Oracle 模式下独有。

正常分配 COUNT 算子的场景

示例 1:含有 ROWNUM 的 SQL 查询正常分配 COUNT 算子场景。

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

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

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

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

Q1: 
obclient> EXPLAIN SELECT c1,ROWNUM FROM t1\G
*************************** 1. row ***************************
Query Plan:
| ====================================
|ID|OPERATOR   |NAME|EST. ROWS|COST|
------------------------------------
|0 |COUNT      |    |1        |37  |
|1 | TABLE SCAN|T1  |1        |36  |
====================================

Outputs & filters: 
-------------------------------------
  0 - output([T1.C1], [rownum()]), filter(nil)
  1 - output([T1.C1]), filter(nil), 
      access([T1.C1]), partitions(p0)

obclient> SELECT c1,ROWNUM FROM t1;
+------+--------+
| C1   | ROWNUM |
+------+--------+
|    1 |      1 |
|    3 |      2 |
|    5 |      3 |
+------+--------+
3 rows in set 

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

信息名称含义
output该算子输出的表达式。 其中 rownum() 表示 ROWNUM 对应的表达式。
filter该算子上的过滤条件。 由于示例中 COUNT 算子没有设置 filter,所以为 nil

从上述执行计划示例的输出结果可以发现,ROWNUM 对应的表达式的初始值为 1,数据每通过一次 COUNT 算子,COUNT 算子就会为 ROWNUM 对应的表达式的值加上 1,实现 ROWNUM 表达式的自增操作。

不分配 COUNT 算子的场景

示例 2:含有 rownum 的 SQL 改写为 LIMIT 后,不分配 COUNT 算子的场景。

Q2:
obclient> EXPLAIN SELECT 1 FROM DUAL WHERE ROWNUM < 2\G
*************************** 1. row ***************************
Query Plan:
| ====================================
|ID|OPERATOR   |NAME|EST. ROWS|COST|
------------------------------------
|0 |LIMIT      |    |1        |1   |
|1 | EXPRESSION|    |1        |1   |
====================================

Outputs & filters: 
-------------------------------------
  0 - output([1]), filter(nil), limit(?), offset(nil)
  1 - output([1]), filter(nil)
      values({1})

从上述执行计划示例的输出结果可以发现,虽然 SQL 中含有 ROWNUM,但是经过 SQL 优化器改写之后,已经将涉及含有 ROWNUM 的表达式转换为了等价的 LIMIT 表达式,转换的好处在于可以做更多的优化,详细信息请参见 LIMIT

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论