All Products
Search
Document Center

PolarDB:Parallel query for cold data

Last Updated:Mar 28, 2026

Elastic Parallel Query (ePQ) accelerates queries on cold data stored in OSS tables by distributing work across multiple worker threads — on one node or across multiple nodes simultaneously.

How it works

ePQ assigns independent scan tasks to parallel workers. Each worker reads a portion of the CSV data in the OSS table concurrently, then the results are aggregated. The degree of parallelism is controlled by the number of workers and the number of nodes involved.

image
Parallel query on cold data supports CSV format only.

Supported versions

All modes require Enterprise Edition.

ModeDatabase engineMinimum revision version
Single-node parallel query (MySQL 8.0.1)MySQL 8.0.18.0.1.1.34
Single-node parallel query (MySQL 8.0.2)MySQL 8.0.28.0.2.2.24
Multi-node parallel queryMySQL 8.0.28.0.2.2.24

Prerequisites

Before you begin, ensure that you have:

image
loose_csv_max_oss_threads controls the maximum number of OSS threads that run in parallel on a single node. Valid values: 1–100. Default: 1. At the default value of 1, parallel query is disabled. Each OSS thread consumes 128 MB of memory, so set this parameter based on available cluster memory.

Run parallel queries on cold data

The examples below use a TPC-H dataset but do not satisfy all requirements of a formal TPC-H benchmark test. Results are not comparable with published TPC-H benchmark results. For details, see TPC-H dataset.

The examples use a table named lineitem archived to OSS in CSV format:

mysql> show create table lineitem;
*************************** 1. row ***************************
       Table: lineitem
Create Table: CREATE TABLE `lineitem` (
  `l_orderkey` int(11) NOT NULL,
  `l_partkey` int(11) NOT NULL,
  `l_suppkey` int(11) NOT NULL,
  `l_linenumber` int(11) NOT NULL,
  `l_quantity` decimal(10,2) NOT NULL,
  `l_extendedprice` decimal(10,2) NOT NULL,
  `l_discount` decimal(10,2) NOT NULL,
  `l_tax` decimal(10,2) NOT NULL,
  `l_returnflag` char(1) NOT NULL,
  `l_linestatus` char(1) NOT NULL,
  `l_shipDATE` date NOT NULL,
  `l_commitDATE` date NOT NULL,
  `l_receiptDATE` date NOT NULL,
  `l_shipinstruct` char(25) NOT NULL,
  `l_shipmode` char(10) NOT NULL,
  `l_comment` varchar(44) NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 /*!99990 800020204 NULL_MARKER='NULL' */ CONNECTION='default_oss_server'

1 row in set (0.00 sec)

To enable parallel query, add the /*+ PARALLEL(N) */ hint to your query, where N is the number of workers per node. To verify whether parallel query is active, run EXPLAIN and check the Extra column:

Extra column valueMeaning
Parallel scan (N workers)Parallel query is active; N is the total number of worker threads across all participating nodes
MPP (N nodes)Multi-node parallel query is active; N is the number of participating nodes

Total parallelism = workers per node × number of nodes.

Serial query

Without the hint, the query runs in a single thread. The Extra column shows Using where with no Parallel scan:

mysql> explain SELECT
    ->     sum(l_extendedprice * l_discount) AS revenue
    -> FROM
    ->     lineitem
    -> WHERE
    ->     l_shipdate >= date '1994-01-01'
    ->     AND l_shipdate < date '1994-01-01' + interval '1' year
    ->     AND l_discount between 0.05 - 0.01 AND 0.05 + 0.01
    ->     AND l_quantity < 24;

+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows     | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+-------------+
|  1 | SIMPLE      | lineitem | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 61560489 |     0.41 | Using where |
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+-------------+

1 row in set, 1 warning (1.23 sec)

The table is scanned and aggregated sequentially in one thread.

Single-node parallel query

Add /*+ PARALLEL(4) */ to distribute the scan across 4 workers on the current node. Parallel scan (4 workers) in the Extra column confirms that parallel query is active:

mysql> explain SELECT /*+ PARALLEL(4) */
    ->     sum(l_extendedprice * l_discount) AS revenue
    -> FROM
    ->     lineitem
    -> WHERE
    ->     l_shipdate >= date '1994-01-01'
    ->     AND l_shipdate < date '1994-01-01' + interval '1' year
    ->     AND l_discount between 0.05 - 0.01 AND 0.05 + 0.01
    ->     AND l_quantity < 24;
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------+
| id | select_type | table       | partitions | type | possible_keys | key  | key_len | ref  | rows     | filtered | Extra                                  |
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------+
|  1 | SIMPLE      | <gather1.1> | NULL       | ALL  | NULL          | NULL | NULL    | NULL |        4 |   100.00 | NULL                                   |
|  1 | SIMPLE      | lineitem    | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 15390122 |     0.41 | Parallel scan (4 workers); Using where |
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------+

2 rows in set, 1 warning (2.17 sec)

Four workers run in parallel on the current node, delivering approximately 4x the throughput of a single-thread query.

Multi-node parallel query

When multiple nodes participate, the Extra column shows both Parallel scan (N workers) and MPP (N nodes). Here, Parallel scan (8 workers) means 8 workers are active in total across all nodes, and MPP (2 nodes) means 2 nodes are participating — 4 workers per node:

mysql> explain SELECT /*+ PARALLEL(4) */
    ->     sum(l_extendedprice * l_discount) AS revenue
    -> FROM
    ->     lineitem
    -> WHERE
    ->     l_shipdate >= date '1994-01-01'
    ->     AND l_shipdate < date '1994-01-01' + interval '1' year
    ->     AND l_discount between 0.05 - 0.01 AND 0.05 + 0.01
    ->     AND l_quantity < 24;
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+-------------------------------------------------------+
| id | select_type | table       | partitions | type | possible_keys | key  | key_len | ref  | rows     | filtered | Extra                                                 |
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+-------------------------------------------------------+
|  1 | SIMPLE      | <gather1.1> | NULL       | ALL  | NULL          | NULL | NULL    | NULL |        1 |   100.00 | NULL                                                  |
|  1 | SIMPLE      | lineitem    | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 59986051 |     0.41 | Parallel scan (8 workers); MPP (2 nodes); Using where |
+----+-------------+-------------+------------+------+---------------+------+---------+------+----------+----------+-------------------------------------------------------+

2 rows in set, 1 warning (0.00 sec)

With 2 nodes and 8 total workers, query throughput is approximately 8x that of a single-thread query.

Troubleshooting

If EXPLAIN shows no Parallel scan in the Extra column, parallel query did not activate. Check the following:

ConditionFix
loose_csv_max_oss_threads is 1 (default)Set it to 2 or higher
Cold data is not in CSV formatConvert data to CSV before archiving
The cluster version does not meet the minimum requirementUpgrade to a supported revision version (see Supported versions)
ePQ is not enabledEnable ePQ (see Enable elastic parallel query)