基本的算子含义和实现方法
发布日期:2025-01-03 18:46 点击次数:165
可下推至DN执行的算子
LogicalView
LogicalView表示从存储层MySQL数据源获取数据的算子,类似于其他数据库中的TableScan或IndexScan,但支持更多的下推。LogicalView中包含下推的SQL语句和数据源信息,更像一个视图。其中下推的SQL可能包含Project、Filter、聚合、排序、Join和子查询等。以下示例展示了LogicalView的输出信息及其含义:explain select * From sbtest1 where id > 1000;返回信息如下:Gather(concurrent=true)
LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)")LogicalView的信息由三部分构成:
tables:存储层MySQL对应的表名,以英文句号.分割,英文句号.之前是分库对应的编号,之后是表名及其编号,如[000-127]表示表名编号从000到127的所有表。
shardCount:需访问的分表总数,该示例会访问从000到127共计128张分表。
sql:下发至存储层MySQL的SQL模版,PolarDB-X在执行时会将表名替换为物理表名,参数化的常量问号?替换成实际参数,详情请参见执行计划管理。
LogicalModifyView
PhyTableOperation
PhyTableOperation表示对某个物理分表直接执行一个操作。
explain insert into sbtest1 values(1, 1, '1', '1'),(2, 2, '2', '2');返回信息如下:PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_001]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_001`,1,1,1,1")
PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_002]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_002`,2,2,2,2")示例中,INSERT插入两行数据,每行数据对应一个PhyTableOperation算子。PhyTableOperation算子的内容包括三部分:
tables:物理表名,仅有唯一一个物理表名。
sql:SQL模版,该SQL模版中表名和常量均被参数化,用?替换,对应的参数在随后的params中给出。
params:SQL模版对应的参数,包括表名和常量。
IndexScan
IndexScan和LogicalView一样也表示从存储层MySQL数据源获取数据的算子,扫描的是索引表。以下示例展示了IndexScan的输出信息及其含义:explain select * from sequence_one_base where integer_test=1;返回信息如下:+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| IndexScan(tables="DRDS_POLARX1_QATEST_APP_000000_GROUP.gsi_sequence_one_index_3a0A_01", sql="SELECT `pk`, `integer_test`, `varchar_test`, `char_test`, `blob_test`, `tinyint_test`, `tinyint_1bit_test`, `smallint_test`, `mediumint_test`, `bit_test`, `bigint_test`, `float_test`, `double_test`, `decimal_test`, `date_test`, `time_test`, `datetime_test`, `timestamp_test`, `year_test`, `mediumtext_test` FROM `gsi_dml_sequence_one_index_index1` AS `gsi_dml_sequence_one_index_index1` WHERE (`integer_test` = ?)") |上述SQL正常应该扫描sequence_one_base表,由于integer_test不是分区键,因此需要扫描sequence_one_base所有的分片。但是由于sequence_one_base表在integer_test列上存在全局二级索引gsi_sequence_one_index,将integer_test=1作为谓词条件对索引表做裁剪,实际上会生成IndexScan算子,表示只会扫描gsi_sequence_one_index索引表的一个分片。