Column Definitions
The ID column is the primary key with auto-increment that we use to maintain the pool range.
Serial is unique and needs to be unique even after partitioning.
The status of a product is an enum with a value of A or U.
Problem:
I want to partition the table on the basis of status. Most SQL queries are based on a primary key or serial number with status A. When I am trying to create a partition using the query below, it is not working.
ALTER TABLE product
PARTITION BY LIST COLUMNS(status)
(
PARTITION used VALUES IN ('U'),
PARTITION used VALUES IN ('A')
);
Error Code : 1503: A Unique Index must include all columns in the table
Can anyone tell me the right approach to solving this problem?
2
Answers
You cannot use ENUM – this datatype is not allowed in the partitioning expression. Use CHAR(1) with CHECK constraint instead. MySQL 8.0.16 or newer needed. If your version is lower then check this condition in the triggers.
You cannot define
serial
as UNIQUE with according index because any unique index must include all columns which are used in the partitioning expression. Use triggers instead.Primary key must be composite – it must include both
status
column (see above) andid
column as a prefix (needed for autoincrementing). If you need to checkid
uniqueness separately then expand the triggers codes accordingly.Sample
Create a table:
Create triggers:
Alter the table, create partitions:
Insert legal rows:
Insert duplicate by
serial
– error:Insert invalid
status
value – error:Update
serial
to existing value – error:Update with
serial
unchanged – allowed by the trigger:See table content:
See single partition content:
fiddle
If
serial
is unique and unlikely to ever change, then get rid ofid
and have a non-partitioned table with(Please explain "maintain the pool range"; maybe
id
has some use.)"want to partition the table on the basis of status". Instead, consider using composite indexes such as
With those,
WHERE status = 'U' ORDER BY created_at DESC
will run as fast or faster without partitioning.And as mentioned by comments, this may be useful in some cases:
"selecting 15000 rows" — What does the client do with so many rows? I would expect it to choke.
You have the date, what is the
id
for?When walking through a large table, "remember where you left off". This can be done even if the PK is composite. Let’s discuss further when I see the various queries you need. (It may involve a composite
PRIMARY KEY
that is designed for performance of those large scans.)More on "left off" in my blog pm Pagination