Chapter 16 · Partitioning, Large Tables, Online DDL, and Data Lifecycle

Partitioning Strategies, Partition Pruning, Keys, Constraints, and Design Limits

Design partitioning as a routing and lifecycle mechanism, then prove optimizer pruning and confront the key/constraint limits that determine whether partitioning is appropriate.

Advanced150–190 minutesPartition design + pruning labMariaDB Community 12.3.2 baselineCurriculum anchor: 11.8 LTS · verify target-version behaviorFree local MariaDB tooling · Last reviewed: August 2026

Learning outcomes

ServiceHub has grown from a small ticketing database into an event platform that retains years of operational telemetry. A query that asks for one recent day should not need to touch every historical chunk, and retention should not mean deleting hundreds of millions of rows one by one. Partitioning can help—but only when its routing rules, key restrictions, optimizer pruning, and operational limits are understood precisely.

01

Distinguish partition routing from partition pruning and explain why partitioning is not automatically a query-speed feature.

02

Choose among RANGE, LIST, HASH, and KEY strategies based on the access/lifecycle problem rather than fashion.

03

Apply MariaDB restrictions on unique keys, storage engines, and foreign keys before designing a partitioned schema.

04

Build a time-series InnoDB table and prove pruning with EXPLAIN PARTITIONS and INFORMATION_SCHEMA.PARTITIONS.

05

Diagnose two realistic partitioning mistakes and repair them without weakening relational correctness.

Version discipline

This lesson uses MariaDB Community Server 12.3.2 as the current lab/reference baseline while retaining the course curriculum anchor of 11.8 LTS. Partitioning behavior is storage-engine and version sensitive. Verify the target version before using limits or maintenance syntax in production.

1. Mental model: one logical table, many physical partitions

A partitioned table is still one SQL table. MariaDB evaluates a partitioning expression to decide which partition owns each row. That write-time decision is routing. On reads, the optimizer may infer that only a subset of partitions can satisfy a predicate; eliminating the rest is partition pruning. Pruning is an optimizer result, not a promise that follows merely from creating partitions.

Term Meaning Operational consequence
partitioning key Column(s)/expression used to route a row Changing it can move a row between partitions.
RANGE / RANGE COLUMNS Partitions cover ordered intervals Natural fit for time-based retention and rolling windows.
LIST / LIST COLUMNS Partitions own enumerated values Useful for small, stable categorical domains.
HASH / LINEAR HASH Expression maps rows across N partitions Distributes data but usually does not provide time-retention semantics.
KEY / LINEAR KEY MariaDB hashes key columns Useful for distribution when an explicit hash expression is undesirable.
pruning Optimizer excludes impossible partitions Must be demonstrated from the real query shape.

MariaDB also supports SYSTEM_TIME partitioning for system-versioned tables, but that is a separate lifecycle mechanism covered later in the course. For this chapter, focus on conventional partitioning of current tables.

2. Verify support and capture a baseline before creating anything

sql · server and partition capability
SELECT VERSION() AS server_version;SHOW PLUGINS;SHOW ENGINES;SELECT @@sql_mode, @@innodb_file_per_table;

Look for active partition support and an available InnoDB engine. “CREATE TABLE succeeded on another MariaDB machine” does not prove your packaged server, storage engine, or version has the same capabilities.

3. Build a time-series table whose keys obey partition rules

MariaDB requires every unique key—including the primary key—to include every column used by the partitioning expression. That requirement affects identifier design. A globally unique event_id by itself cannot be the primary key if the table is partitioned by event_day.

sql · create the disposable ServiceHub table
DROP DATABASE IF EXISTS servicehub16_l1;CREATE DATABASE servicehub16_l1;USE servicehub16_l1;CREATE TABLE ticket_events (  event_id BIGINT NOT NULL AUTO_INCREMENT,  event_day DATE NOT NULL,  ticket_id BIGINT NOT NULL,  event_type VARCHAR(32) NOT NULL,  payload VARCHAR(255) NULL,  created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),  PRIMARY KEY (event_id, event_day),  KEY ix_ticket_day (ticket_id, event_day)) ENGINE=InnoDBPARTITION BY RANGE COLUMNS(event_day) (  PARTITION p2026q1 VALUES LESS THAN ('2026-04-01'),  PARTITION p2026q2 VALUES LESS THAN ('2026-07-01'),  PARTITION p2026q3 VALUES LESS THAN ('2026-10-01'),  PARTITION p2026q4 VALUES LESS THAN ('2027-01-01'),  PARTITION p_future VALUES LESS THAN (MAXVALUE));INSERT INTO ticket_events(event_day,ticket_id,event_type,payload) VALUES('2026-02-10',101,'created','web'),('2026-05-12',101,'assigned','queue-a'),('2026-08-03',202,'created','api'),('2026-11-18',303,'closed','resolved');
sql · observe partition metadata
SELECT PARTITION_NAME, PARTITION_ORDINAL_POSITION,       PARTITION_DESCRIPTION, TABLE_ROWSFROM INFORMATION_SCHEMA.PARTITIONSWHERE TABLE_SCHEMA='servicehub16_l1'  AND TABLE_NAME='ticket_events'ORDER BY PARTITION_ORDINAL_POSITION;

TABLE_ROWS is metadata and may be estimated for InnoDB; use it to understand partition shape, not as an exact accounting ledger.

4. Prove pruning instead of assuming it

sql · query aligned with the partitioning key
EXPLAIN PARTITIONSSELECT event_id,ticket_id,event_typeFROM ticket_eventsWHERE event_day >= '2026-08-01'  AND event_day <  '2026-09-01';

The partitions column should identify p2026q3 for this predicate. That proves the optimizer can derive the relevant range. It does not prove the query is fast: index selectivity, row count inside the partition, cache state, and result volume still matter.

sql · contrast a predicate that cannot prune by date
EXPLAIN PARTITIONSSELECT event_id,event_day,event_typeFROM ticket_eventsWHERE event_type='created';

Because event_type does not constrain event_day, multiple/all partitions can remain candidates. Partitioning did not replace the need for suitable indexes.

5. Wrong approach #1: keep a primary key that omits the partitioning column

sql · deliberately invalid design
CREATE TABLE bad_events (  event_id BIGINT PRIMARY KEY,  event_day DATE NOT NULL,  payload VARCHAR(100)) ENGINE=InnoDBPARTITION BY RANGE COLUMNS(event_day) (  PARTITION p_old VALUES LESS THAN ('2026-07-01'),  PARTITION p_new VALUES LESS THAN (MAXVALUE));

MariaDB rejects this design because the primary key does not include event_day. A representative error is ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function. The repair is not to remove uniqueness blindly; redesign the key so every unique key contains the partitioning column, and verify whether that changes application lookup semantics.

6. Wrong approach #2: add a foreign key to a partitioned InnoDB table

sql · foreign-key limitation
CREATE TABLE tickets (  ticket_id BIGINT PRIMARY KEY) ENGINE=InnoDB;ALTER TABLE ticket_events  ADD CONSTRAINT fk_event_ticket  FOREIGN KEY (ticket_id) REFERENCES tickets(ticket_id);

Current MariaDB partitioning does not allow a partitioned table to contain or be referenced by foreign keys. The operation fails rather than quietly weakening integrity. If the domain requires database-enforced referential integrity, partitioning this table may be the wrong design. Application-side checks are not automatically equivalent to an InnoDB foreign key.

7. Design limits that should influence the decision

Constraint Why it matters
Every unique key includes partition columns Can widen primary/secondary indexes and change application lookup patterns.
No foreign keys on/referencing partitioned tables May conflict directly with relational integrity requirements.
All partitions use one supported engine You cannot treat partitions as arbitrary per-engine mini-tables.
Many partitions add metadata/operational cost A very high partition count can hurt management and planning.
Cross-partition queries are not automatically parallel Partitioning is not a substitute for distributed execution.
Pruning depends on predicates Poor query shapes may still scan many partitions.

8. Production judgment and cleanup

Use partitioning when the partition key aligns with a real management or access boundary—especially time-based retention, archival, or predictable pruning. Do not introduce it solely because a table is “large.” First prove the bottleneck, check key/FK consequences, measure representative plans, and document how partitions will be created, monitored, backed up, and retired.

Prerequisites and boundaries

Prerequisites: MariaDB Community Server 12.3.2 lab (curriculum anchor 11.8 LTS), active partitioning support, InnoDB, and a disposable account with CREATE/ALTER/DROP plus normal DML privileges. Production designs must re-check target-version partition limits and storage-engine support.

Check your understanding

  1. What is the difference between partition routing and partition pruning?
  2. Why must event_day appear in every UNIQUE/PRIMARY key in the lab table?
  3. What does EXPLAIN PARTITIONS prove, and what does it not prove?
  4. Why can partitioning conflict with a schema that depends on foreign keys?
  5. When is a RANGE time partition a stronger design choice than HASH partitioning?
Review the answers

Routing decides where a row belongs; pruning decides which partitions a read can skip. MariaDB requires all partition-expression columns in every unique key. EXPLAIN PARTITIONS proves optimizer partition selection, not end-to-end latency. Current MariaDB partitioned tables cannot participate in foreign keys. RANGE is especially useful when ordered time boundaries match pruning and lifecycle actions such as dropping old partitions.

sql · cleanup
DROP DATABASE IF EXISTS servicehub16_l1;

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.