Cassandra ORDER BY

The ORDER BY clause in CQL controls the sort order of rows returned within a partition. Unlike SQL, Cassandra's ORDER BY is strictly limited to clustering columns within a single partition. You cannot order by a column that is not a clustering column, and you cannot sort rows across different partitions.

How Cassandra Stores Rows

Cassandra always writes rows within a partition in the sort order defined by the clustering columns. This physical sort order is set at table creation time with the CLUSTERING ORDER BY clause. Changing the ORDER BY direction in a SELECT simply reads those pre-sorted rows forward or backward.

Table: messages
PRIMARY KEY (room_id, sent_at)
CLUSTERING ORDER BY (sent_at ASC)   -- default ascending storage order

Physical disk layout:

room_id='chat-1':
  [sent_at: 2024-06-01 08:00] → "Good morning"
  [sent_at: 2024-06-01 08:05] → "Ready for the call?"
  [sent_at: 2024-06-01 08:10] → "Starting now"
  [sent_at: 2024-06-01 08:30] → "Wrapping up"

ORDER BY ASC (Default)

SELECT * FROM messages
WHERE room_id = 'chat-1'
ORDER BY sent_at ASC;
Result:
sent_at                  | sender | body
─────────────────────────────────────────────────────
2024-06-01 08:00:00      | alice  | Good morning
2024-06-01 08:05:00      | bob    | Ready for the call?
2024-06-01 08:10:00      | alice  | Starting now
2024-06-01 08:30:00      | carol  | Wrapping up

ORDER BY DESC

Reversing the sort order tells Cassandra to read the SSTable from the end of the partition backward. This is equally fast — Cassandra simply reads in reverse.

SELECT * FROM messages
WHERE room_id = 'chat-1'
ORDER BY sent_at DESC;
Result (newest first):
sent_at                  | sender | body
─────────────────────────────────────────────────────
2024-06-01 08:30:00      | carol  | Wrapping up
2024-06-01 08:10:00      | alice  | Starting now
2024-06-01 08:05:00      | bob    | Ready for the call?
2024-06-01 08:00:00      | alice  | Good morning

Define Default Sort at Table Creation

Set the default sort direction in the table definition so SELECT queries without ORDER BY return rows in the order your application uses most.

CREATE TABLE messages (
  room_id  TEXT,
  sent_at  TIMESTAMP,
  sender   TEXT,
  body     TEXT,
  PRIMARY KEY (room_id, sent_at)
) WITH CLUSTERING ORDER BY (sent_at DESC);

Now SELECT * FROM messages WHERE room_id = 'chat-1' returns the newest message first without any ORDER BY in the query.

Multiple Clustering Columns and ORDER BY

When a table has multiple clustering columns, ORDER BY must list them in the order they appear in the PRIMARY KEY definition. You can change only the last column's direction — all preceding columns must match their table-level CLUSTERING ORDER setting.

CREATE TABLE game_scores (
  game_id   TEXT,
  level     INT,
  player_id UUID,
  score     INT,
  PRIMARY KEY (game_id, level, player_id)
) WITH CLUSTERING ORDER BY (level ASC, player_id ASC);

-- Valid: matches clustering column order
SELECT * FROM game_scores
WHERE game_id = 'chess-pro'
ORDER BY level ASC, player_id ASC;

-- Valid: reverse both
SELECT * FROM game_scores
WHERE game_id = 'chess-pro'
ORDER BY level DESC, player_id DESC;

-- Invalid: mix of ASC and DESC (not allowed in CQL)
SELECT * FROM game_scores
WHERE game_id = 'chess-pro'
ORDER BY level ASC, player_id DESC;

ORDER BY Does Not Work Across Partitions

ORDER BY only sorts rows within a single partition. Cassandra cannot sort rows that live on different nodes in a cluster-wide sort. If you need global ordering, bring results to the application layer and sort them there.

Single partition — ORDER BY works:
  WHERE room_id = 'chat-1'
  ORDER BY sent_at DESC  ✓

Cross-partition — ORDER BY not allowed:
  WHERE room_id IN ('chat-1', 'chat-2')
  ORDER BY sent_at DESC  ✗  (CQL error)

ORDER BY with LIMIT

Combining ORDER BY with LIMIT is the standard pattern for "get the most recent N items" queries.

-- Latest 10 messages in a chat room:
SELECT * FROM messages
WHERE room_id = 'chat-1'
ORDER BY sent_at DESC
LIMIT 10;

Performance of ORDER BY

Because rows are already physically sorted on disk, ORDER BY in Cassandra adds almost zero overhead. Reading in reverse (DESC when the table is stored ASC, or vice versa) requires a backward SSTable scan, which is slightly less cache-friendly than forward reads but still very fast in practice.

Summary

ORDER BY in CQL sorts rows within a partition by one or more clustering columns. You can sort ascending or descending, but all clustering columns in ORDER BY must appear in their defined order and with consistent direction. Set the default sort order at table creation time using CLUSTERING ORDER BY. For "latest N items" patterns, combine ORDER BY DESC with LIMIT for fast, efficient reads.

Leave a Comment

Your email address will not be published. Required fields are marked *