[TOC] # SUBPLAN SCAN SUBPLAN SCAN 算子用于展示优化器从哪个视图访问数据。 当查询的 FROM TABLE 为视图时,执行计划中会分配 SUBPLAN SCAN 算子。SUBPLAN SCAN 算子类似于 TABLE SCAN 算子,但它不从基表读取数据,而是读取孩子节点的输出数据。 如下示例中,Q1 查询中 1 号算子为视图中查询生成,0 号算子 SUBPLAN SCAN 读取 1 号算子并输出。 ~~~ obclient>CREATE TABLE t1(c1 INT, 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) obclient>CREATE VIEW v AS SELECT * FROM t1 LIMIT 5; Query OK, 1 rows affected (0.12 sec) Q1: obclient>EXPLAIN SELECT * FROM V WHERE c1 > 0\G; *************************** 1. row *************************** Query Plan: ===================================== |ID|OPERATOR |NAME|EST. ROWS|COST| ------------------------------------- |0 |SUBPLAN SCAN|v |1 |37 | |1 | TABLE SCAN |t1 |2 |37 | ===================================== Outputs & filters: ------------------------------------- 0 - output([v.c1], [v.c2]), filter([v.c1 > 0]), access([v.c1], [v.c2]) 1 - output([t1.c1], [t1.c2]), filter(nil), access([t1.c1], [t1.c2]), partitions(p0), limit(5), offset(nil) ~~~ **说明** 目前 LIMIT 算子只支持 MySQL 模式的 SQL 场景。详细信息请参考[LIMIT](https://open.oceanbase.com/docs/community/oceanbase-database/V3.1.0/LIMIT-1-2)。 上述示例中,Q1 查询的执行计划展示中的 outputs & filters 详细列出了 SUBPLAN SCAN 算子的输出信息如下: <table data-tag="table" id="table-dtz-0iq-atz" class="table"><colgroup span="1" width="139" data-tag="col" id="col-93d-5nh-ejd" colwidth="1*" colnum="1" colname="col1" style="width:50%" class="col"></colgroup><colgroup span="1" width="609" data-tag="col" id="col-kqj-xo2-n7c" colwidth="1*" colnum="2" colname="col2" style="width:50%" class="col"></colgroup><thead id="thead-6o9-ar8-vex" class="thead"><tr id="tr-lha-je6-rz7"><th id="td-zd9-hxc-bc2"><p id="p-uwd-0yy-bos"><b>信息名称</b></p></th><th id="td-qkg-ebl-1r0"><p id="p-kx5-v8q-4c9"><b>含义</b></p></th></tr></thead><tbody data-tag="tbody" id="tbody-432-fkz-d5h" class="tbody"><tr data-tag="tr" id="tr-l7q-ixz-pnl" class="tr"><td data-tag="td" id="td-lix-ere-61s" class="td"><p id="p-573-1bx-020">output</p></td><td data-tag="td" id="td-jiu-tjj-vtd" class="td"><p id="p-u54-dx7-y9k">该算子输出的表达式。</p></td></tr><tr data-tag="tr" id="tr-oq6-bvq-2ga" class="tr"><td data-tag="td" id="td-5qh-3wh-y6e" class="td"><p id="p-nr1-uru-wuf">filter</p></td><td data-tag="td" id="td-7h8-po1-k3o" class="td"><p id="p-jys-l5e-4wh">该算子上的过滤条件。</p><p id="p-3db-mb5-7ay">例如 <code data-tag="code" class="code">filter([v.c1 &gt; 0])</code> 中的 <code data-tag="code" class="code">v.c1 &gt; 0</code>。</p></td></tr><tr data-tag="tr" id="tr-c1l-lnh-syr" class="tr"><td data-tag="td" id="td-u8j-dsr-ykh" class="td"><p data-tag="p" id="p-zua-cd4-lqw" class="p">access</p></td><td data-tag="td" id="td-cff-h6w-2cw" class="td"><p data-tag="p" id="p-45n-vvl-8ne" class="p">该算子从子节点读取的需要使用的列名。</p></td></tr></tbody></table> 当`FROM TABLE`为视图并且查询满足一定条件时能够对查询进行视图合并改写,此时执行计划中并不会出现 SUBPLAN SCAN。如下例所示,Q2 查询相比 Q1 查询减少了过滤条件,不再需要分配 SUBPLAN SCAN 算子。 ~~~ Q2: obclient>EXPLAIN SELECT * FROM v\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(5), offset(nil) ~~~