Indexes
We can create an index on only part of the table:
Taking an example of a users
table with this schema and
data:
= CREATE TABLE users (
db- id serial,
db- username text,
db- activated boolean
db-);
dbCREATE TABLE
Seed the table:
= INSERT INTO users (username, activated)
db- SELECT
db- md5(random()::text) AS username,
db- random() < 0.9 AS activated
db- FROM
db- generate_series(1, 1000000);
dbINSERT 0 1000000
= SELECT activated, count(*) FROM users GROUP BY activated;
dbcount
activated | -----------+--------
102567
f | 897433
t |
= VACUUM ANALYZE users;
db VACUUM
We know that if we index the id of users
, since we know
that 90% of the users aren't signed up, we can index only that part of
the data:
= CREATE INDEX users_unactivated_partial_ix ON users(id)
db- WHERE not activated;
dbCREATE INDEX
If we select using this index, the database uses this index:
= EXPLAIN SELECT * FROM users WHERE not activated;
dbQUERY PLAN
------------------------
Index Scan using users_unactivated_partial_ix on users (cost=0.29..3493.60 rows=102567 width=38)
And the index is about 10% the size of a full index:
= \di+ users_unactivated_partial_ix
dbList of relations
Schema | Name | Type | Owner | Table | Size
--------+------------------------------+-------+-------+-------+---------
public | users_unactivated_partial_ix | index | haki | users | 2216 kB