Indexes (GIN, GiST, SP-GiST, BRIN, B-tree, Hash, partial, covering)

Django ORM PostgreSQL May 22, 2026 python

Indexes live in a model's Meta.indexes; migrations emit the CREATE INDEX DDL shown below (read live from pg_indexes).

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# ======================================================================
# Indexes live in a model's `Meta.indexes`; migrations emit the `CREATE INDEX`
# DDL shown below (read live from `pg_indexes`). PostgreSQL has many index
# types: GIN for arrays/jsonb/full-text, GiST & SP-GiST for ranges, BRIN for
# huge time-ordered tables, B-tree for ordering, Hash for equality, plus partial
# (`condition=`) and covering (`include=`) indexes, and per-type options
# (`fastupdate`, `pages_per_range`, `fillfactor`).
# ======================================================================

# ----------------------------------------------------------------------
# indexes across the three tables (live from pg_indexes)
# ----------------------------------------------------------------------

# Django:
class Book(models.Model):
    class Meta:
        indexes = [
            GinIndex(fields=["tags"], fastupdate=False),          # arrays / jsonb (+option)
            GinIndex(fields=["search"]),                          # full-text
            GinIndex(OpClass(F("title"), name="gin_trgm_ops")),   # trigram
            BrinIndex(fields=["published"], pages_per_range=64),  # time-ordered (+option)
            BTreeIndex(fields=["pages"], fillfactor=90),          # ordering (+option)
            Index(fields=["price"], condition=Q(is_active=True)), # partial
            Index(fields=["author"], include=["title", "price"]), # covering
        ]

class Reservation(models.Model):
    class Meta:
        indexes = [
            GistIndex(fields=["during"]),                         # GiST for ranges
            SpGistIndex(fields=["during"]),                       # SP-GiST for ranges
        ]

class Server(models.Model):
    class Meta:
        indexes = [HashIndex(fields=["hostname"])]                # hash index

# SQL:
#   CREATE INDEX book_active_price ON public.examples_book USING btree (price) WHERE is_active;
#
#   CREATE INDEX book_author_cover ON public.examples_book USING btree (author_id) INCLUDE (title, price);
#
#   CREATE INDEX book_pages_btree ON public.examples_book USING btree (pages) WITH (fillfactor='90');
#
#   CREATE INDEX book_pub_brin ON public.examples_book USING brin (published) WITH (pages_per_range='64');
#
#   CREATE INDEX book_search_gin ON public.examples_book USING gin (search);
#
#   CREATE INDEX book_tags_gin ON public.examples_book USING gin (tags) WITH (fastupdate=off);
#
#   CREATE INDEX book_title_trgm ON public.examples_book USING gin (title gin_trgm_ops);
#
#   CREATE INDEX examples_book_author_id_ab830087 ON public.examples_book USING btree (author_id);
#
#   CREATE UNIQUE INDEX examples_book_pkey ON public.examples_book USING btree (id);
#
#   CREATE UNIQUE INDEX uq_book_title_author_ci ON public.examples_book USING btree (lower((title)::text), author_id);
#
#   CREATE UNIQUE INDEX examples_reservation_pkey ON public.examples_reservation USING btree (id);
#
#   CREATE INDEX exclude_overlapping_reservations ON public.examples_reservation USING gist (room, during);
#
#   CREATE INDEX resv_during_gist ON public.examples_reservation USING gist (during);
#
#   CREATE INDEX resv_during_spgist ON public.examples_reservation USING spgist (during);
#
#   CREATE UNIQUE INDEX examples_server_pkey ON public.examples_server USING btree (id);
#
#   CREATE INDEX server_host_hash ON public.examples_server USING hash (hostname)

# Result:
#   book_active_price
#   book_author_cover
#   book_pages_btree
#   book_pub_brin
#   book_search_gin
#   book_tags_gin
#   book_title_trgm
#   examples_book_author_id_ab830087
#   examples_book_pkey
#   uq_book_title_author_ci
#   examples_reservation_pkey
#   exclude_overlapping_reservations
#   resv_during_gist
#   resv_during_spgist
#   examples_server_pkey
#   server_host_hash