Flexible Parallelism
On this page
SingleStore supports Flexible Parallelism, which allows multiple cores on the same node to access the same database partition.
With Flexible Parallelism, as database partitions are created, they are divided into sub-partitions.
As an example, if you are currently at one partition per core with Flexible Parallelism, doubling the size of your cluster and then rebalancing will result in two cores for each partition.
Typically, analytic or hybrid transactional/analytic workloads will gain some benefits from Flexible Parallelism, especially over time as you add more hardware and rebalance clusters.
As you add cores to your SingleStore system, you can reach a point where you have more cores than database partitions on each leaf node.
Note
When Flexible Parallelism is enabled, all new databases created will use Flexible Parallelism.
Note
SingleStore recommends lowering parallelism by setting query_
for high-throughput search workloads.
The default setting query_
indicates a parallelism of one thread per core for each query.
Flexible Parallelism is disabled by default in SingleStore in version 7.
Enabling and Configuring Flexible Parallelism
You cannot enable or disable Flexible Parallelism on existing databases.CREATE TABLE LIKE
and INSERT…SELECT
.
Flexible Parallelism is enabled and configured via two engine variables.sub_
engine variable enables Flexible Parallelism, and query_
controls whether queries use flexible parallelism or not.
Set sub_
to a valid value greater than 0 (a power of 2 up to 64) to enable Flexible Parallelism.
When a database is created with sub_
set to a valid value greater than 0, it will support Flexible Parallelism for queries over columnstore tables in that database.sub_
.
Once Flexible Parallelism is enabled, you can configure CPU usage per query on each leaf node.
To control the fraction of the CPU power that will be dedicated to one query on each leaf node, set the query_
engine variable on the aggregator.
For example, if you want to use half of the available cores on each leaf node to process one query, then set query_
to 0.
If you want to limit the parallelism to use a specific number of cores to process each query, rather than just a proportion of the number of cores, then you will need to know how many cores there are on each leaf.expected_
variable.
The degree of parallelism on each node is calculated as expected_
, rounded to the nearest integer.
Suppose expected_
is 28 and you want to use 10 cores on each leaf node to process a query.query_
to .
How to Tell When Flexible Parallelism is Being Used
You can determine if Flexible Parallelism is enabled for a particular database by looking at the sub-partition count in the Information Schema DISTRIBUTED_
or MV_
views.
SELECT * FROM information_schema.DISTRIBUTED_DATABASES;
+-------------+---------------+----------------+--------------------+------------+-------------+---------+--------------------+-----------+---------+
| DATABASE_ID | DATABASE_NAME | NUM_PARTITIONS | NUM_SUB_PARTITIONS | CLUSTER_ID | REMOTE_NAME | IS_SYNC | IS_SYNC_DURABILITY | IS_PAUSED | SITE_ID |
+-------------+---------------+----------------+--------------------+------------+-------------+---------+--------------------+-----------+---------+
| 4 | db | 3 | 24 | 0 | | 1 | 0 | 0 | 1 |
+-------------+---------------+----------------+--------------------+------------+-------------+---------+--------------------+-----------+---------+
In these views, databases with a non-zero value in the NUM_
column have Flexible Parallelism enabled.
You can determine if a specific query is using Flexible Parallelism by using EXPLAIN or PROFILE.parallelism_
for operations like Gather, GatherMerge, Project, Repartition, Broadcast, and MaterializedCTE.
Example output from EXPLAIN
for a SELECT *
query is below.
EXPLAIN SELECT * FROM example_table;
+--------------------------------------------------------------------------------------------------+
| EXPLAIN |
+--------------------------------------------------------------------------------------------------+
| Gather partitions:all alias:remote_0 parallelism_level:segment |
| Project [example_table.a, example_table.b] |
| ColumnStoreScan example_db.example_table, SORT KEY __UNORDERED () table_type:sharded_columnstore |
+--------------------------------------------------------------------------------------------------+
In this example, Gather partitions:all alias:remote_
indicates that parallelism_
is segment
for the Gather
operator in this query.
In general, the parallelism_
can be partition
, sub_
, or segment
.
A parallelism_
of partition indicates one thread is used per database partition and that the query is not using Flexible Parallelism.
The values sub_
and segment
both indicate that Flexible Parallelism is being used.sub_
and segment
is the granularity of the work items in the query threads.sub_
case, each thread scans a pre-computed set of sub-partitions.segment
case, there is not a pre-computed split of work across threads; rather, when a thread finishes its work, that thread may be assigned another segment to scan.
Segment level parallelism allows threads that finish their work earlier to help other threads (at a segment granularity), while sub-partition level parallelism does not allow that behavior.
There are certain situations when Flexible Parallelism is enabled (query_
is not 0
), but queries do not use Flexible Parallelism.parallelism_
will be partition
.
Last modified: March 31, 2025