LIMIT 算子用于限制数据输出的行数,这与 MySQL 的 LIMIT 算子功能相同。
在 OceanBase 数据库中处理含有 LIMIT 的 SQL 语句时,SQL 优化器都会为其生成一个 LIMIT 算子,但在一些特殊场景不会给与分配,例如 LIMIT 可以下压到基表的场景,就没有分配的必要性。
含有 LIMIT 算子的 SQL 场景
示例 1:OceanBase 数据库含有 LIMIT 算子的 SQL 场景
obclient> CREATE TABLE t1(c1 INT, c2 INT);
Query OK, 0 rows affected
obclient> CREATE TABLE t2(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(2, 2);
Query OK, 1 rows affected
obclient> INSERT INTO t1 VALUES(3, 3);
Query OK, 1 rows affected
obclient> INSERT INTO t2 VALUES(1, 1);
Query OK, 1 rows affected
obclient> INSERT INTO t2 VALUES(2, 2);
Query OK, 1 rows affected
obclient> INSERT INTO t2 VALUES(3, 3);
Query OK, 1 rows affected
Q1:
obclient> EXPLAIN SELECT t1.c1 FROM t1,t2 LIMIT 1 OFFSET 1\G
*************************** 1. row ***************************
Query Plan: =====================================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-----------------------------------------------------
|0 |LIMIT | |1 |91 |
|1 | NESTED-LOOP JOIN CARTESIAN| |2 |91 |
|2 | SUBPLAN SCAN |VIEW1|1 |46 |
|3 | TABLE SCAN |t1 |1 |46 |
|4 | MATERIAL | |2 |46 |
|5 | SUBPLAN SCAN |VIEW2|2 |46 |
|6 | TABLE SCAN |t2 |2 |46 |
=====================================================
Outputs & filters:
-------------------------------------
0 - output([VIEW1.t1.c1]), filter(nil), rowset=256, limit(1), offset(1)
1 - output([VIEW1.t1.c1]), filter(nil), rowset=256,
conds(nil), nl_params_(nil)
2 - output([VIEW1.t1.c1]), filter(nil), rowset=256,
access([VIEW1.t1.c1])
3 - output([t1.c1]), filter(nil), rowset=256,
access([t1.c1]), partitions(p0),
limit(1 + 1), offset(nil)
4 - output(nil), filter(nil), rowset=256
5 - output(nil), filter(nil), rowset=256,
access(nil)
6 - output([1]), filter(nil), rowset=256,
access(nil), partitions(p0),
limit(1 + 1), offset(nil)
Q2:
obclient> EXPLAIN SELECT * FROM t1 LIMIT 2\G
*************************** 1. row ***************************
Query Plan:
| ===================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
-----------------------------------
|0 |TABLE SCAN|t1 |2 |37 |
===================================
Outputs & filters:
-------------------------------------
0 - output([t1.c1], [t1.c2]), filter(nil),
access([t1.c1], [t1.c2]), partitions(p0),
limit(2), offset(nil)
上述示例中,Q1 查询的执行计划展示中的 outputs & filters 详细列出了 LIMIT 算子的输出信息如下:
| 信息名称 | 含义 |
|---|---|
| output | 该算子输出的表达式。 |
| filter | 该算子上的过滤条件。 由于示例中 LIMIT 算子没有设置 filter,所以为 nil。 |
| limit | 限制输出的行数,是一个常量。 |
| offset | 距离当前位置的偏移行数,是一个常量。 由于示例中的 SQL 中不含有 offset,因此生成的计划中为 nil。 |
Q2 查询的执行计划展示中,虽然 SQL 中含有 LIMIT,但是并未分配 LIMIT 算子,而是将相关表达式下压到了 TABLE SCAN 算子上,这种下压 LIMIT 行为是 SQL 优化器的一种优化方式,详细信息请参见 TABLE SCAN。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




