obkv的全表扫描纯内存操作为何这么快

【 使用环境 】生产环境 or 测试环境
【 OB or 其他组件 】OB
【 使用版本 】5.7.25-OceanBase_CE-v4.3.0.1

表结构:

obclient [tpch10]> show create table orders \G
*************************** 1. row ***************************
       Table: orders
Create Table: CREATE TABLE `orders` (
  `O_ORDERKEY` bigint(20) NOT NULL,
  `O_CUSTKEY` bigint(20) NOT NULL,
  `O_ORDERSTATUS` char(1) NOT NULL,
  `O_TOTALPRICE` decimal(15,2) NOT NULL,
  `O_ORDERDATE` date NOT NULL,
  `O_ORDERPRIORITY` char(15) NOT NULL,
  `O_CLERK` char(15) NOT NULL,
  `O_SHIPPRIORITY` bigint(20) NOT NULL,
  `O_COMMENT` varchar(79) NOT NULL,
  PRIMARY KEY (`O_ORDERKEY`)
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0
1 row in set (0.002 sec)

SQLAudit信息:

                         SVR_IP: 192.168.31.201
                       SVR_PORT: 2882
                     REQUEST_ID: 134421
                    SQL_EXEC_ID: 1614477
                       TRACE_ID: YB42C0A81FC9-00061776EA5B8669-0-0
                            SID: 3221493326
                      CLIENT_IP: 192.168.31.200
                    CLIENT_PORT: 49138
                      TENANT_ID: 1004
                    TENANT_NAME: test
            EFFECTIVE_TENANT_ID: 1004
                        USER_ID: 200001
                      USER_NAME: root
                     USER_GROUP: 0
                 USER_CLIENT_IP: 192.168.31.200
                          DB_ID: 500002
                        DB_NAME: tpch10
                         SQL_ID: 438CA6574AC9A49852223DCB7D3BB28E
                      QUERY_SQL: select sum(O_TOTALPRICE),count(O_TOTALPRICE) from orders where O_ORDERPRIORITY != 'asdf'
                        PLAN_ID: 489
                  AFFECTED_ROWS: 0
                    RETURN_ROWS: 1
                  PARTITION_CNT: 1
                       RET_CODE: 0
                          QC_ID: 0
                         DFO_ID: 0
                         SQC_ID: 0
                      WORKER_ID: 0
                          EVENT: 
                         P1TEXT: 
                             P1: 0
                         P2TEXT: 
                             P2: 0
                         P3TEXT: 
                             P3: 0
                          LEVEL: 0
                  WAIT_CLASS_ID: 100
                    WAIT_CLASS#: 0
                     WAIT_CLASS: OTHER
                          STATE: MAX_WAIT TIME ZERO
                WAIT_TIME_MICRO: 0
          TOTAL_WAIT_TIME_MICRO: 0
                    TOTAL_WAITS: 0
                      RPC_COUNT: 0
                      PLAN_TYPE: 1
                   IS_INNER_SQL: 0
                IS_EXECUTOR_RPC: 0
                    IS_HIT_PLAN: 1
                   REQUEST_TIME: 1714657983733244
                   ELAPSED_TIME: 96385
                       NET_TIME: 0
                  NET_WAIT_TIME: 4
                     QUEUE_TIME: 136
                    DECODE_TIME: 0
                  GET_PLAN_TIME: 44
                   EXECUTE_TIME: 96135
          APPLICATION_WAIT_TIME: 0
          CONCURRENCY_WAIT_TIME: 0
              USER_IO_WAIT_TIME: 0
                  SCHEDULE_TIME: 0
                  ROW_CACHE_HIT: 0
         BLOOM_FILTER_CACHE_HIT: 0
                BLOCK_CACHE_HIT: 28232
                     DISK_READS: 0
                      RETRY_CNT: 0
                     TABLE_SCAN: 1
              CONSISTENCY_LEVEL: 3
        MEMSTORE_READ_ROW_COUNT: 0
         SSSTORE_READ_ROW_COUNT: 0
            DATA_BLOCK_READ_CNT: 0
           DATA_BLOCK_CACHE_HIT: 28002
           INDEX_BLOCK_READ_CNT: 0
          INDEX_BLOCK_CACHE_HIT: 230
            BLOCKSCAN_BLOCK_CNT: 28002
              BLOCKSCAN_ROW_CNT: 15000000
PUSHDOWN_STORAGE_FILTER_ROW_CNT: 15000000
            REQUEST_MEMORY_USED: 90112
          EXPECTED_WORKER_COUNT: 0
              USED_WORKER_COUNT: 0
                     SCHED_INFO: NULL
             FUSE_ROW_CACHE_HIT: 0
              PS_CLIENT_STMT_ID: -1
               PS_INNER_STMT_ID: -1
                          TX_ID: 0
               SNAPSHOT_VERSION: 1714657983626196927
                   REQUEST_TYPE: 2
          IS_BATCHED_MULTI_STMT: 0
                  OB_TRACE_INFO: NULL
                      PLAN_HASH: 2076616277034537960
             LOCK_FOR_READ_TIME: 0
                   PARAMS_VALUE: 
                      RULE_NAME: 
                  PARTITION_HIT: 1
            TX_INTERNAL_ROUTING: 0
               TX_STATE_VERSION: 0
                   FLT_TRACE_ID: 
                    PL_TRACE_ID: NULL
                PLSQL_EXEC_TIME: 0
  TOTAL_MEMSTORE_READ_ROW_COUNT: 0
   TOTAL_SSSTORE_READ_ROW_COUNT: 0

在做完合并,并且纯内存读取操作情况下(OB、MySQL数据全都放在内存中),OB为何远比MySQL快呢,做1500万的全表扫描查询(而且BLOCKSCAN_BLOCK_CNT: 28002数量也是不少的)仅需要96ms,有没有介绍OBKV顺序扫描这块是如何优化的文章?

应该是没有。
Oceanbase在合并操作后,数据全都放在内存中,纯内存读取操作可以提高查询效率。对于1500万的全表扫描查询,OB只需要96ms的时间,是因为OBKV顺序扫描的优化。OBKV通过索引、数据结构优化、预读和缓存等技术,使得顺序扫描效率非常高。同时,OB还支持并行扫描、增量扫描等技术,进一步提高了查询效率

ob和mysql全表扫描性能的差异一个是数据的存储结构的差异,另一个主要的原因是可能是oceanbase的向量化执行引擎,可以看一下下面的文章
https://www.oceanbase.com/news/ly37vv

我将建表编码设置为flat(纯行格式),然后设置了_rowsets_max_rows=1(算是关闭向量计算了吧)。我看还是比其它数据库(纯内存操作)快很多,这是为何呢?在哪里做的优化呢。
通过测试来看flat行格式比pax格式慢3-4倍左右,但是flat格式的情况下还是很快,有点超出预期。我理解不应该比堆表的扫描快,但是看起来比mysql(btree类型表)和pg(堆表)都要快不少的。

可以对比一下和MySQL相比处理的数据库块数有什么区别,同样的数据,在不同的数据库内存储的结构可能有差异。

obkv底层还是通用数据库

快是因为sum和count都下压到存储层计算, 和是否向量化关系不大
如果是列存表, 你这个查询应该会更快

1 个赞