VillageSQL is a drop-in replacement for MySQL with extensions.
All examples in this guide work on VillageSQL. Install Now →
When Partitioning Helps
Partition pruning delivers real gains when:- The table is too large to fit in the buffer pool and queries consistently filter on the partition key
- You regularly drop old data —
ALTER TABLE t DROP PARTITION p_oldis instant vs. a slow DELETE
- Queries don’t filter on the partition key (all partitions must be scanned)
- The table fits comfortably in memory
- You’re trying to replace proper indexing — a good index on a non-partitioned table often outperforms a partitioned table without matching indexes
RANGE Partitioning
Rows are assigned to partitions based on whether the partition key falls within a range. The most common use case is date-based archival.MAXVALUE partition to catch rows that don’t fit any defined range. Without it, inserts outside the defined ranges fail with an error.
Add a new partition:
LIST Partitioning
Rows are assigned based on exact values in the partition key.LIST COLUMNS for string columns — LIST alone only supports integer expressions.
HASH and KEY Partitioning
HASH and KEY distribute rows evenly across a fixed number of partitions. They don’t support partition pruning by value but can improve concurrent write throughput by spreading rows across partitions.
Partition Pruning
Pruning only activates when theWHERE clause filters directly on the partition expression. With RANGE COLUMNS (created_at), filtering on created_at prunes correctly:
EXPLAIN and check the partitions column:
partitions shows only one or a few partition names, pruning is working. If it shows all partitions, the filter isn’t being applied.
Partitioning Constraints
- Every unique key (including the primary key) must include all columns in the partitioning expression. If you want to partition by
created_at, every unique key must containcreated_at— you can’t add a partition to a table with a standalonePRIMARY KEY (id)unless you first change it toPRIMARY KEY (id, created_at). FOREIGN KEYconstraints are not supported on partitioned tables in MySQL.- A table can have a maximum of 8192 partitions (MySQL 8.0+).
Partitioning vs Indexing
Start with indexing. Add partitioning only when you have a demonstrated performance problem on a large table and a clear partition key that matches your query patterns.
Frequently Asked Questions
Can I partition an existing table?
Yes, withALTER TABLE:
How do I check which partition a row is in?
EXPLAIN PARTITIONS with a WHERE clause matching that row.
Troubleshooting
See also
- How InnoDB Stores Data — the storage engine that partitioning operates on
- How MySQL Indexes Work — indexes within partitions and partition pruning
- Schema Migrations in MySQL — how to add or change partitioning on existing tables

