OceanBase logo

OceanBase

A unified distributed database ready for your transactional, analytical, and AI workloads.

Product Overview
DEPLOY YOUR WAY

OceanBase Cloud

The best way to deploy and scale OceanBase

OceanBase Enterprise

Run and manage OceanBase on your infra

TRY OPEN SOURCE

OceanBase Community Edition

The free, open-source distributed database

OceanBase seekdb

Open source AI native search database

Customer Stories

Real-world success stories from enterprises across diverse industries.

View All
BY USE CASES

Mission-Critical Transactions

Global & Multicloud Application

Elastic Scaling for Peak Traffic

Real-time Analytics

Active Geo-redundancy

Database Consolidation

Resources

Comprehensive knowledge hub for OceanBase.

Blog

Live Demos

Training & Certification

Documentation

Official technical guides, tutorials, API references, and manuals for all OceanBase products.

View All
PRODUCTS

OceanBase Cloud

OceanBase Database

Tools

Connectors and Middleware

QUICK START

OceanBase Cloud

OceanBase Database

BEST PRACTICES

Practical guides for utilizing OceanBase more effectively and conveniently

Company

Learn more about OceanBase – our company, partnerships, and trust and security initiatives.

About OceanBase

Partner

Trust Center

Contact Us

International - English
中国站 - 简体中文
日本 - 日本語
Sign In
Start on Cloud

OceanBase

A unified distributed database ready for your transactional, analytical, and AI workloads.

Product Overview
DEPLOY YOUR WAY

OceanBase Cloud

The best way to deploy and scale OceanBase

OceanBase Enterprise

Run and manage OceanBase on your infra

TRY OPEN SOURCE

OceanBase Community Edition

The free, open-source distributed database

OceanBase seekdb

Open source AI native search database

Customer Stories

Real-world success stories from enterprises across diverse industries.

View All
BY USE CASES

Mission-Critical Transactions

Global & Multicloud Application

Elastic Scaling for Peak Traffic

Real-time Analytics

Active Geo-redundancy

Database Consolidation

Comprehensive knowledge hub for OceanBase.

Blog

Live Demos

Training & Certification

Documentation

Official technical guides, tutorials, API references, and manuals for all OceanBase products.

View All
PRODUCTS
OceanBase CloudOceanBase Database
ToolsConnectors and Middleware
QUICK START
OceanBase CloudOceanBase Database
BEST PRACTICES

Practical guides for utilizing OceanBase more effectively and conveniently

Learn more about OceanBase – our company, partnerships, and trust and security initiatives.

About OceanBase

Partner

Trust Center

Contact Us

Start on Cloud
编组
All Products
    • Databases
    • iconOceanBase Database
    • iconOceanBase Cloud
    • iconOceanBase Tugraph
    • iconInteractive Tutorials
    • iconOceanBase Best Practices
    • Tools
    • iconOceanBase Cloud Platform
    • iconOceanBase Migration Service
    • iconOceanBase Developer Center
    • iconOceanBase Migration Assessment
    • iconOceanBase Admin Tool
    • iconOceanBase Loader and Dumper
    • iconOceanBase Deployer
    • iconKubernetes operator for OceanBase
    • iconOceanBase Diagnostic Tool
    • iconOceanBase Binlog Service
    • Connectors and Middleware
    • iconOceanBase Database Proxy
    • iconEmbedded SQL in C for OceanBase
    • iconOceanBase Call Interface
    • iconOceanBase Connector/C
    • iconOceanBase Connector/J
    • iconOceanBase Connector/ODBC
    • iconOceanBase Connector/NET
icon

OceanBase Database

SQL - V4.1.0

    Download PDF

    OceanBase logo

    The Unified Distributed Database for the AI Era.

    Follow Us
    Products
    OceanBase CloudOceanBase EnterpriseOceanBase Community EditionOceanBase seekdb
    Resources
    DocsBlogLive DemosTraining & CertificationTicket
    Company
    About OceanBaseTrust CenterLegalPartnerContact Us
    Follow Us

    © OceanBase 2026. All rights reserved

    Cloud Service AgreementPrivacy PolicySecurity
    Contact Us
    Document Feedback
    1. Documentation Center
    2. OceanBase Database
    3. SQL
    4. V4.1.0
    iconOceanBase Database
    SQL - V 4.1.0
    Databases
    • OceanBase Database
    • OceanBase Cloud
    • OceanBase Tugraph
    • Interactive Tutorials
    • OceanBase Best Practices
    Tools
    • OceanBase Cloud Platform
    • OceanBase Migration Service
    • OceanBase Developer Center
    • OceanBase Migration Assessment
    • OceanBase Admin Tool
    • OceanBase Loader and Dumper
    • OceanBase Deployer
    • Kubernetes operator for OceanBase
    • OceanBase Diagnostic Tool
    • OceanBase Binlog Service
    Connectors and Middleware
    • OceanBase Database Proxy
    • Embedded SQL in C for OceanBase
    • OceanBase Call Interface
    • OceanBase Connector/C
    • OceanBase Connector/J
    • OceanBase Connector/ODBC
    • OceanBase Connector/NET
    SQL
    KV
    • V 4.6.0
    • V 4.4.2
    • V 4.3.5
    • V 4.3.3
    • V 4.3.1
    • V 4.3.0
    • V 4.2.5
    • V 4.2.2
    • V 4.2.1
    • V 4.2.0
    • V 4.1.0
    • V 4.0.0
    • V 3.1.4 and earlier

    Pagination queries

    Last Updated:2023-07-28 02:55:43  Updated
    Share
    What is on this page
    Optimize query by page
    Pagination based on the unique key
    Pagination based on subqueries and delayed association
    Case analysis

    folded

    Share

    Optimize query by page

    If a large number of results are expected for a database query, we recommend that you perform the query by page.

    Pagination based on the unique key

    Example: perform a pagination query based on the unique key.

    obclient> select * from tb where c1 = 'xxx' and c2 = 'xxx' and id > 'xxx' limit 100;
    

    This statement reserves the ID of the last row of every 100 rows as the condition value for the next 100 rows. The c1, c2, and id columns are used to create a composite index.

    Notice

    1. This method is suitable for querying tables with even data distribution. It does not show the expected performance if the query generates 100 results per page only by scanning tens or hundreds of thousands of rows.
    2. The select * from tb where id > '' limit 100; statement applies to table scans where the query results are paged only by the id column.

    Pagination based on subqueries and delayed association

    Instead of skipping the offset rows, OceanBase Database retrieves offset+N rows, drops the offset rows, and then returns the N rows. Therefore, when the number of offset rows is large, the query efficiency is low. In this case, you can control the total number of returned pages, or rewrite the SQL statements if the page number exceeds a specific threshold.

    • Control the total number of returned pages.

      You need to code the logic of a pagination query in a way that the query directly returns N rows without executing the pagination statement if the total number of offset rows is 0.

      For example, if a transaction returns more than 1,000 pages of results, when the user clicks the last page, the database is almost paralyzed.

    • Rewrite the SQL statements when the page number exceeds a specific threshold.

      In the following example, the statement is rewritten to perform a subquery, which quickly locates the ID range to be retrieved, and then associates it with the query condition.

      obclient> select a.name from a,(select id from a where id LIMIT 100000,20) b where a.id=b.id;
      

    Case analysis

    Create a table by executing the following sample statements:

    obclient> CREATE TABLE `business_case_analysis_effect_receive_catalog_details` (
      `id` bigint(10) NOT NULL AUTO_INCREMENT,
      `province_code` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT '330000' COMMENT 'Province code',
      `province_name` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT 'Zhejiang' COMMENT 'Province name',
      `area_code` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT 'City code',
      `area_name` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT 'City name',
      `region_code` varchar(50) CHARACTER SET utf8 NOT NULL COMMENT 'District/county code',
      `region_name` varchar(50) CHARACTER SET utf8 NOT NULL COMMENT 'District/county name',
      `dept_code` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT 'Department code',
      `dept_name` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT 'Department name',
      `catalog_id` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Catalog ID',
      `catalog_name` varchar(500) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Catalog name',
      `catalog_code` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Catalog code',
      `business_code` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Business code',
      `business_name` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT 'Business name',
      `received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received parcels',
      `app_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by app',
      `pc_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by PC',
      `hall_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received in hall',
      `window_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by window',
      `two_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received parcels 2.0',
      `two_app_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by app 2.0',
      `two_pc_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by PC 2.0',
      `two_hall_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received in hall 2.0',
      `two_window_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by window 2.0',
      `one_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received parcels 1.0',
      `one_app_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by app 1.0',
      `one_pc_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received by PC 1.0',
      `one_hall_received_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Received in hall 1.0',
      `item_flag` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT 'Item 2.0 (0-No, 1-Yes)',
      `stat_date` datetime NOT NULL COMMENT 'Statistical time, which is the time when the data was generated, typically the previous day.',
      `delete_flag` int(1) NOT NULL DEFAULT '0' COMMENT 'Deleted (0-NO, 1-Yes)',
      `gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation time',
      `gmt_updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update time',
      `not_case_assigned_code_num` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Number of not collected parcels with code assigned',
      `item_type_code` varchar(50) CHARACTER SET utf8 NOT NULL COMMENT 'Item type ID',
      `item_dock_type` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT 'Item docking method (0-All, 1-Overall docking, 2-Docking form 2.0)',
      `apply_person_type` varchar(20) CHARACTER SET utf8 NOT NULL COMMENT 'Applicant type (0-All, 1-Individual, 2-Legal person)',
      `two_not_case_assigned_code_num` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Number of not collected parcels with code assigned 2.0',
      `one_not_case_assigned_code_num` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Number of not collected parcels with code assigned 1.0',
      `self_service_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Parcels by self-service lockers',
      `two_self_service_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Parcels by self-service lockers 2.0',
      `one_self_service_num` bigint(11) NOT NULL DEFAULT '0' COMMENT 'Parcels by self-service lockers 1.0',
      PRIMARY KEY (`id`) USING BTREE,
      KEY `query_catalog_index` (`catalog_id`,`catalog_code`,`stat_date`,`area_code`,`region_code`,`dept_code`,`business_code`,`business_name`) USING BTREE GLOBAL,
      KEY `idx_area_region` (`area_code`,`region_code`,`item_flag`,`item_type_code`) USING BTREE GLOBAL,
      KEY `idx_statDate` (`stat_date`,`area_code`,`region_code`) USING BTREE GLOBAL,
      KEY `idx_catalog_code` (`catalog_code`,`catalog_id`) USING BTREE GLOBAL,
      KEY `idx_item_type_code` (`item_type_code`) USING BTREE GLOBAL,
      KEY `idx_catalog_business` (`catalog_code`,`catalog_id`,`business_code`) USING BTREE GLOBAL
    ) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Business dashboard - processing - processing results - parcels received - catalog distribution';
    

    Original SQL statements for the query:

    SELECT
      catalog_id AS catalogId,
      catalog_name AS catalogName,
      catalog_code AS catalogCode,
      business_code AS businessCode,
      business_name AS businessName,
      IFNULL(
        CAST(
          SUM(pc_received_num) / SUM(received_num) AS DECIMAL(14, 4)
        ),
        0
      ) AS networkHandlePercent,
      IFNULL(
        CAST(
          SUM(app_received_num) / SUM(received_num) AS DECIMAL(14, 4)
        ),
        0
      ) AS palmtopHandlePercent,
      IFNULL(
        CAST(
          SUM(two_received_num) /(
            SUM(received_num) + SUM(not_case_assigned_code_num)
          ) AS DECIMAL(14, 4)
        ),
        0
      ) AS netHandleRate,
      IFNULL(SUM(not_case_assigned_code_num), 0) AS notCaseAssignedCodeNum,
      IFNULL(SUM(received_num), 0) AS receivedNum,
      IFNULL(SUM(two_received_num), 0) AS twoReceivedNum,
      IFNULL(SUM(pc_received_num), 0) AS pcReceivedNum,
      IFNULL(SUM(app_received_num), 0) AS appReceivedNum,
      IFNULL(SUM(hall_received_num), 0) AS hallReceivedNum,
      IFNULL(SUM(two_window_received_num), 0) AS windowReceivedNum,
      IFNULL(SUM(self_service_num), 0) AS selfServiceNum
    FROM
      business_case_analysis_effect_receive_catalog_details
    WHERE
      stat_date <= 'xxxx-xx-xx'
      AND stat_date >= 'xxxx-xx-xx'
      AND item_type_code in ("xx", "xx", "xx", "xx", "xx", "xx", "xx")
    GROUP BY
      catalog_code,
      catalog_id
    LIMIT
      offset, 15;
    

    The table contains 5 million data records.

    The following table shows the execution time in seconds after the modification of offset:

    Offset
    0
    100
    300
    500
    1000
    2000
    Execution duration (s) 0.07 3.96 6.83 8.67 14.44 18.04

    No index is created for the table. Therefore, the execution time does not change much after an index is specified in the WHERE clause. In this case, parallel execution is considered. The following part shows the optimized SQL statements:

    SELECT
      /*+ PARALLEL(5),USE_HASH_AGGREGATION*/
      catalog_id AS catalogId,
      catalog_name AS catalogName,
      catalog_code AS catalogCode,
      business_code AS businessCode,
      business_name AS businessName,
      IFNULL(
        CAST(
          SUM(pc_received_num) / SUM(received_num) AS DECIMAL(14, 4)
        ),
        0
      ) AS networkHandlePercent,
      IFNULL(
        CAST(
          SUM(app_received_num) / SUM(received_num) AS DECIMAL(14, 4)
        ),
        0
      ) AS palmtopHandlePercent,
      IFNULL(
        CAST(
          SUM(two_received_num) /(
            SUM(received_num) + SUM(not_case_assigned_code_num)
          ) AS DECIMAL(14, 4)
        ),
        0
      ) AS netHandleRate,
      IFNULL(SUM(not_case_assigned_code_num), 0) AS notCaseAssignedCodeNum,
      IFNULL(SUM(received_num), 0) AS receivedNum,
      IFNULL(SUM(two_received_num), 0) AS twoReceivedNum,
      IFNULL(SUM(pc_received_num), 0) AS pcReceivedNum,
      IFNULL(SUM(app_received_num), 0) AS appReceivedNum,
      IFNULL(SUM(hall_received_num), 0) AS hallReceivedNum,
      IFNULL(SUM(two_window_received_num), 0) AS windowReceivedNum,
      IFNULL(SUM(self_service_num), 0) AS selfServiceNum
    FROM
      business_case_analysis_effect_receive_catalog_details
    WHERE
      stat_date <= 'xxxx-xx-xx'
      AND stat_date >= 'xxxx-xx-xx'
      AND item_type_code in ("xx", "xx", "xx", "xx", "xx", "xx", "xx")
    GROUP BY
      catalog_code,
      catalog_id
    LIMIT
      offset, 15;
    

    The optimized SQL statements are re-executed based on the offset described in the preceding table, and the query takes about 5 seconds to return results for each offset.

    Notice

    The case analysis shows that:

    • A query in an OceanBase cluster takes more time to return the results as the number of offset rows increases.
    • The optimal performance is achieved when you set the degree of parallelism to the number of partitions of the table.

    Previous topic

    Weak consistency read
    Last

    Next topic

    Overview
    Next
    What is on this page
    Optimize query by page
    Pagination based on the unique key
    Pagination based on subqueries and delayed association
    Case analysis