Performance

An index serves a question, not a column

Difficulty 3/5Free

An activity feed stores events. There are a lot of them, and exactly two queries matter:

  1. A user's most recent events. WHERE user_id = ? ORDER BY at DESC LIMIT 20. This runs on every page load.
  2. Deduplication on write. Clients retry, so each event carries an idempotency key, and the same user must never end up with two events carrying the same key. A retry has to be rejected by the database, not by the application checking first.

The rules:

  • Both queries must be answered using an index, with no sort and no scan of the whole table.
  • The duplicate key for the same user is refused. Two different users may of course use the same key.
  • An event belongs to a user that exists.

users already exists, and the table is seeded with twenty thousand events after your schema is created.

The one thing that is fixed

2 relations

The tests reference these names. Everything else is yours, and is what is being assessed: extra tables, extra columns, types, constraints, indexes.

  • users

    id

  • events

    iduser_idatidempotency_key

The schema that already exists

This runs before your submission. Do not repeat it, extend it.

prelude.sql
CREATE TABLE users (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
);

INSERT INTO users SELECT FROM generate_series(1, 500);
PostgreSQL DDL: tables, constraints, indexes
schema.sql

Tab indents · ⌘/Ctrl + Enter runs

What will be checked

7 tests
  • ····The user's recent events are found through an index
  • ····And without sorting the rows afterwards
  • ····And it returns the newest event first
  • ····The same user cannot reuse an idempotency key
  • ····A different user may use the same key
  • ····The deduplication check is itself an index lookup
  • ····An event cannot belong to a user that does not exist