COUNT演算子は、OracleのROWNUM機能との互換性を保つために使用され、ROWNUM式の自動インクリメント操作を実現します。
一般的なシナリオでは、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;
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;
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を参照してください。