index_advisor: query optimization
Index advisor is a Postgres extension for recommending indexes to improve query performance.
For example:
index_advisor( 'select book.id from book where title = $1' );
startup_cost_before | startup_cost_after | total_cost_before | total_cost_after | index_statements | errors
---------------------+--------------------+-------------------+------------------+-----------------------------------------------------+--------
0 . 00 | 1 . 17 | 25 . 88 | 6 . 40 | { "CREATE INDEX ON public.book USING btree (title)" },| {}
Features:
Supports generic parameters e.g. $1
, $2
Supports materialized views
Identifies tables/columns obfuscaed by views
Skips duplicate indexes
index_advisor is a trusted language extension, which means it is directly installable by users from the database.dev SQL package repository.
To get started, enable the dbdev client by executing the setup SQL script .
Then, install index_advisor by running
select dbdev . install ( 'olirice-index_advisor' );
create extension if not exists hypopg;
create extension "olirice-index_advisor" ;
Index advisor exposes a single function index_advisor(query text)
that accepts a query and searches for a set of SQL DDL create index
statements that improve the query's execution time.
The function's signature is:
index_advisor(query text )
startup_cost_before jsonb,
startup_cost_after jsonb,
As a minimal example, the index_advisor
function can be given a single table query with a filter on an unindexed column.
create extension if not exists index_advisor cascade;
index_advisor( 'select book.id from book where title = $1' );
startup_cost_before | startup_cost_after | total_cost_before | total_cost_after | index_statements | errors
---------------------+--------------------+-------------------+------------------+-----------------------------------------------------+--------
0 . 00 | 1 . 17 | 25 . 88 | 6 . 40 | { "CREATE INDEX ON public.book USING btree (title)" },| {}
and will return a row recommending an index on the unindexed column.
More complex queries may generate additional suggested indexes:
create extension if not exists index_advisor cascade;
author_id int not null references author(id),
publisher_id int not null references publisher(id),
book_id int references book(id),
publisher.name as publisher_name,
author.name as author_name,
on book.publisher_id = publisher.id
on book.author_id = author.id
on book.id = review.book_id
startup_cost_before | startup_cost_after | total_cost_before | total_cost_after | index_statements | errors
---------------------+--------------------+-------------------+------------------+-----------------------------------------------------------+--------
27 . 26 | 12 . 77 | 68 . 48 | 42 . 37 | { "CREATE INDEX ON public.book USING btree (author_id)" , | {}
"CREATE INDEX ON public.book USING btree (publisher_id)" ,
"CREATE INDEX ON public.review USING btree (book_id)" }
index_advisor will only recommend single column, B-tree indexes. More complex indexes will be supported in future releases.
when a generic argument's type is not discernible from context, an error is returned in the errors
field. To resolve those errors, add explicit type casting to the argument. e.g. $1::int
.