Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 21, 2021 11:32 am GMT

Postgres indexes

Indexing is a technique to make queries run faster, different indexes are suitable for different queries, the main differences are between an exact match, ranges and a full-text, in a nutshell if your query has a exact match or a range you should use the default method, otherwise use gist.

most of the information from this post came from here, have a read if you want to dig deeper.

How to create a index

CREATE INDEX [UNIQUE] INDEX_NAME ON TABLE_NAME [USING METHOD](  COLUMN_NAME [ASC | DESC] [NULL { FIRST | LAST}])

e.g:

CREATE INDEX idx_title ON cards 

Remove an index

DROP INDEX  [ CONCURRENTLY][ IF EXISTS ]  index_name [ CASCADE | RESTRICT ];

identify if a query uses an index

You can use EXPLAIN to identify if a query is using an specific index

EXPLAIN SELECT * FROM BOOKS WHERE BOOK = "MY BOOK";

if your query is using the index something like "Index Scan "
will appear e.g:

index is not being used

                        QUERY PLAN--------------------------------------------------------------- Seq Scan on cards  (cost=0.00..62.50 rows=828 width=242)

index is being used

                               QUERY PLAN----------------------------------------------------------------------------- Index Scan using my_index on cards  (cost=0.28..8.29 rows=1 width=242)   Index Cond: ((title)::text = 'a'::text)

my_index is the name of the index, cards is the name of the table and
title is the name of the column

List all indexes in a table

the following will list all indexes related to your tables, you can also
filter indexes for a specific table or field

select tablename, indexname from pg_indexes where schemaname = 'public';

Index Methods

The following are the most common index methods.

Generalized Inverted Indexes(GIN)

Good for full-text search, maps multiple values to a column

Generalized Serch Tree(Gist)

Allows for balanced btree, good for full-text search, used for geometric data types(poligons points etc..)
are usefull for operations besides comparison and range.

Hash Index

It's trash, not worth the complexity and work to manage it, coudn't find any common example that couldn't be done with the other methods in an easier way with better results, you can try to convince me otherwise in the comments if you want.

btree index

Doesn't work with like queries, works pretty well with caching, it's the default index, if you don't pass the method option when creating the index it will be created with this method.

These are all the most common indexes, now let's talk about some techniques when creating indexes

Expression Indexes

expression indexes are usefull when you need to convert the data before searching it.

CREATE INDEX USERS_LOWER_EMAIL ON USERS(LOWER(EMAIL));

the above index will be used in searches like

WHERE lower(email) = '<lowercased-email>'
CREATE INDEX articles_day ON articles ( date(published_at) )

the above can will be used for

WHERE date(articles.published_at) = date('2011-03-07')

Partial Indexes

partial index is a index applied to just part of the data, the following is a usefull partial index

CREATE INDEX articles_flagged_created_at_index ON articles(created_at) WHERE flagged IS TRUE;

Unique Indexes

create unique <index_name> .....

Improves query performance, if you try to create a uniq index in a column that has rows with the same value the index creation will fail.
if you try to insert values that already exist in a column with a uniq index a error occurs

ERROR:  duplicate key value violates unique constraint "uniq_index"DETAIL:  Key (title)=(title 1) already exists.

When it makes sense to use indexes?

The general rule is, the bigger your table is the better
index only makes sense when the cost of reading data from the index(hitting the disc) and then reading data from the table is lower than a table scan, so in general big tables
are better for indexes because you don't need to scan the whole table and the cost of reading two different values in two different tables isn't very high comparatively with the full table scan, when in doubt just create a test case and test it or better yet, always test it first.

Who decides when to use an index or not?

The query planner decides to use an index or not, just because an index exists and your query
matches the initial criteria for using that index, doesn't mean that the index will be used.
the query planner decides when to use the index or not based on a multitude of factors, the biggest
one is how much data the query will hit, if it's a lot it's more likely that the query planner will use the index
indexes make more sense the bigger the table is.

You need a lot of data to test indexes properly,

A good general rule is to test as close to production as you can. the query planer might decide not to use your index if you test it locally in small sets of data, which will make you waste a lot of time benchmarking with non sensical data, trust me I've learned the hard way.
so you should create a lot of data to test your indexes, the general rule is to test as close to production as possible

creating indexes locks your db

If it's a big table your db can be locked for hours, use create index concurrently to mitigate the problem

Reindexing

after sometime your index will not be optimized anymore, that's when you need to reindex it
a good reindex technique is to create another index with a different name and then droping the old one.

and that's pretty much all the basic information that you need to start creating indexes, go create some indexes and make your queries run faster!


Original Link: https://dev.to/____marcell/postgres-indexes-4603

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To