Adds or changes the PRIMARY KEY (ORDER BY) expression of a ClickHouse MergeTree table to speed up data skipping and look-ups.
Add a Primary Key in ClickHouse
ALTER TABLE … MODIFY PRIMARY KEY lets you define or change the key ClickHouse uses for data skipping, greatly improving query speed.
ClickHouse stores data in MergeTree
engines. PRIMARY KEY
is effectively an alias for the ORDER BY
clause, controlling how parts are sorted on disk. Updating it rewrites future parts and accelerates range queries.
Yes—use ALTER TABLE … MODIFY PRIMARY KEY
. Existing parts are not rewritten automatically, but new inserts will follow the new key. Run an OPTIMIZE TABLE
to backfill.
Lead with the most selective, frequently filtered columns. For an Orders
table, (customer_id, order_date)
filters by customer then narrows by date, yielding high selectivity.
MergeTree
and its derivatives (ReplacingMergeTree
, ReplicatedMergeTree
, etc.) support the clause.
Query system.tables
to see primary_key
and sorting_key
expressions before altering.
Use ALTER TABLE … MODIFY PRIMARY KEY
with the new expression.
Run OPTIMIZE TABLE … FINAL
during low-traffic windows to merge old parts under the new order.
Leading with order_date
instead of customer_id
in a multi-tenant store results in large ranges scanned. Fix by reordering the key or adding the selective column first.
Without OPTIMIZE TABLE FINAL
, historical data remains unsorted; queries gain no benefit. Schedule an optimize or run a background materialized view to rewrite data.
-- Step 1: create table without primary key
a CREATE TABLE Orders (
id UInt64,
customer_id UInt64,
order_date DateTime,
total_amount Decimal(10,2)
) ENGINE = MergeTree ORDER BY id;
-- Step 2: add a better primary key
ALTER TABLE Orders MODIFY PRIMARY KEY (customer_id, order_date);
-- Step 3: backfill
OPTIMIZE TABLE Orders FINAL;
If the table is monstrously large and historical queries are rare, the gain may not justify the rewrite cost.
No. PRIMARY KEY controls ordering for data skipping; it does not guarantee uniqueness. Use ReplacingMergeTree
or AggregatingMergeTree
with a unique field if needed.
Yes. If you omit PRIMARY KEY, the ORDER BY expression acts as both sorting and primary key expression. Setting PRIMARY KEY explicitly lets you have a wider ORDER BY but narrower key.
You cannot remove it entirely, but you can modify it again. Ensure the replacement expression starts with the desired leading columns.