From c40bf30dbb9cfdd5f1ab960547fe2692394d3d5d Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Fri, 4 Aug 2023 16:36:44 -0500 Subject: [PATCH 01/20] add indexing guide and index advisor extension --- .../NavigationMenu.constants.ts | 5 + .../docs/pages/guides/database/extensions.mdx | 7 +- .../database/extensions/index_advisor.mdx | 147 ++++++++++++++++++ .../guides/database/query-optimization.mdx | 134 ++++++++++++++++ 4 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 apps/docs/pages/guides/database/extensions/index_advisor.mdx create mode 100644 apps/docs/pages/guides/database/query-optimization.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 6dbec8a0a36..94d6249babd 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -539,6 +539,7 @@ export const database: NavMenuConstant = { { name: 'Implementing Cascade Deletes', url: '/guides/database/postgres/cascade-deletes' }, { name: 'Implementing column encryption', url: '/guides/database/column-encryption' }, { name: 'Partitioning your tables', url: '/guides/database/partitions' }, + { name: 'Query Optimization', url: '/guides/database/query-optimization' }, { name: 'Testing your database', url: '/guides/database/testing' }, { name: 'Managing Timeouts', url: '/guides/database/timeouts' }, { name: 'Managing Passwords', url: '/guides/database/managing-passwords' }, @@ -559,6 +560,10 @@ export const database: NavMenuConstant = { url: '/guides/database/extensions/plv8', }, { name: 'http: RESTful Client', url: '/guides/database/extensions/http' }, + { + name: 'index_advisor: Query optimization', + url: '/guides/database/extensions/index_advisor', + }, { name: 'PGAudit: Postgres Auditing', url: '/guides/database/extensions/pgaudit', diff --git a/apps/docs/pages/guides/database/extensions.mdx b/apps/docs/pages/guides/database/extensions.mdx index 8b729b6ba73..45b743ab41d 100644 --- a/apps/docs/pages/guides/database/extensions.mdx +++ b/apps/docs/pages/guides/database/extensions.mdx @@ -1,9 +1,10 @@ import Layout from '~/layouts/DefaultGuideLayout' export const meta = { - id: 'extensions', - title: 'Postgres Extensions Overview', - description: 'Using Postgres extensions.', + +id: 'extensions', +title: 'Postgres Extensions Overview', +description: 'Using Postgres extensions.', } Extensions are exactly as they sound - they "extend" the database with functionality which isn't part of the Postgres core. diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx new file mode 100644 index 00000000000..8ba0e81140b --- /dev/null +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -0,0 +1,147 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'index-advisor', + title: 'index_advisor: query optimization', + description: 'Automatically optimize SQL queries', +} + +[Index advisor](https://github.com/supabase/index_advisor) is a Postgres extension for recommending indexes to improve query performance. + +Features: + +- Supports generic parameters e.g. `$1`, `$2` +- Supports materialized views +- Identifies tables/columns obfuscaed by views +- Skips duplicate indexes + +## Installation + +index_advisor is a trusted language extension, which means it is directly installable by users from the [database.dev](database.dev) SQL package repository. + +To get started, enable the dbdev client by executing the [setup SQL script](https://database.dev/installer). + +Then, install index_advisor by running + +```sql +select dbdev.install('olirice-index_advisor'); +create extension if not exists hypopg; +create extension "olirice-index_advisor" + version '0.1.0'; +``` + +## API + +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: + +```sql +index_advisor(query text) +returns + table ( + startup_cost_before jsonb, + startup_cost_after jsonb, + total_cost_before jsonb, + total_cost_after jsonb, + index_statements text[], + errors text[] + ) +``` + +## Usage + +As a minimal example, the `index_advisor` function can be given a single table query with a filter on an unindexed column. + +```sql +create extension if not exists index_advisor cascade; + +create table book( + id int primary key, + title text not null +); + +select + * +from + 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)"},| {} +(1 row) +``` + +and will return a row recommending an index on the unindexed column. + +More complex queries may generate additional suggested indexes + +```sql +create extension if not exists index_advisor cascade; + +create table author( + id serial primary key, + name text not null +); + +create table publisher( + id serial primary key, + name text not null, + corporate_address text +); + +create table book( + id serial primary key, + author_id int not null references author(id), + publisher_id int not null references publisher(id), + title text +); + +create table review( + id serial primary key, + book_id int references book(id), + body text not null +); + +select + * +from + index_advisor(' + select + book.id, + book.title, + publisher.name as publisher_name, + author.name as author_name, + review.body review_body + from + book + join publisher + on book.publisher_id = publisher.id + join author + on book.author_id = author.id + join review + on book.id = review.book_id + where + author.id = $1 + and publisher.id = $2 + '); + + 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)"} +(3 rows) +``` + +## Limitations + +Currently, index_advisor will only recommend single column, B-tree indexes. This restriction will be relaxed in future releases. + +## Resources + +- Official [`index_advisor` GitHub Repository](https://github.com/supabase/index_advisor) + +export const Page = ({ children }) => + +export default Page diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx new file mode 100644 index 00000000000..ecae3fc4559 --- /dev/null +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -0,0 +1,134 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + title: 'Query Optimization', + description: 'Choosing indexes', + footerHelpType: 'postgres', +} + +When working with PostgreSQL, or any relational database, indexing is key to improving query performance. +Aligning indexes with common query patterns can speed up data retrieval by order of magnitude. + +This guide is intended to: + +- help identify parts of a query that have the potential to be improved by indexes +- introduce the most frequently applicable indexing tool + +It is in no way comprehensive and should be thought of as a starting point on your optimization journey. + +If you're new to query optimization, you may be interested in [index_advisor](/docs/guides/database/extensions/index_advisor), our tool for automatically detecting indexes that improve performance on a given query. + +## Example Query + +Consider the following example query that retrieves customer names and purchase dates from two tables: + +```sql +select + a.name, + b.date_of_purchase +from + customers a + join orders b + on a.id = b.customer_id +where + a.sign_up_date > '2023-01-01' + and b.status = 'shipped' +order by + b.date_of_purchase; +limit 10 +``` + +In this query, there are several parts indexes could likely help in optimizing the performance: + +### `where` Clause: + +The `where` clause filters rows based on certain conditions, and indexing the columns involved can improve this process: + +- `a.sign_up_date`: If filtering by `sign_up_date` is common, indexing this column can speed up the query. +- `b.status`: Indexing the status may be beneficial if the column has diverse values. + +```sql +create index idx_customers_sign_up_date on customers (sign_up_date); + +create index idx_orders_status on orders (status); +``` + +### `join` Columns + +Indexes on the columns used for joining tables can help Postgres avoid scanning tables in their entirety when connecting tables. + +- Indexing and `b.customer_id` would likely improve the performance of the join in this query. +- Note that if `a.id` is the primary key of the `customers` table it is already indexed + +```sql +create index idx_orders_customer_id on orders (customer_id); +``` + +### `order by` Clause + +Sorting can also be optimized by indexing: + +- An index on `b.date_of_purchase` wcan improve the sorting process, and is particularly beneficial when a subset of rows is being returned with a `limit` clause. + +```sql +create index idx_orders_date_of_purchase on orders (date_of_purchase); +``` + +## Key Concepts + +Here are some concepts and tools to keep in mind to help you identify the best index for the job, and measure the impact that your index had: + +### Analyze the Query Plan + +Use the `explain` command to understand the query's execution. Look for slow parts, such as Sequential Scans or high cost numbers. If creating an index does not reduce the cost of the query plan, remove it. + +For example: + +```sql +explain select * from customers where sign_up_date > 25; +``` + +### Use Appropriate Index Types + +PostgreSQL offers various index types like [B-tree, Hash, GIN, etc](https://www.postgresql.org/docs/current/indexes-types.html). Select the type that best suits your data and query pattern. Using the right index type can make a significant difference. For example, using a BRIN index on field that is always increasing on a table with infrequent updates, like `created_at` on an `orders` table, routinely results in indexes that are +10x smaller than the equivalent default B-tree index. That translates into better scalability. + +```sql +create index idx_orders_created_at ON customers using brin(created_at); +``` + +### Partial Indexes + +For queries that frequently target a subset of data, a partial index could be faster and smaller than indexing the entire column. A partial index contains a `where` clause to filter the values included in the index. Note that a query's `where` clause must match the index for it to be used. + +```sql +create index idx_orders_status on orders (status) +where status = 'shipped'; +``` + +### Composite Indexes + +If filtering or joining on multiple columns, a composite index can help postgres referring to multiple indexes to identify the relevant rows. + +```sql +create index idx_customers_sign_up_date_priority on customers (sign_up_date, priority); +``` + +### Over-Indexing + +Avoid the urge to index columns you operate on infrequently. While indexes can speed up reads, they also slow down writes, so its important to balance those factors when making indexing decisions. + +### Statistics + +Postgres maintains a set of statistics about the contents of your tables. Those statistics are used by the query planner to decide e.g. when its is more efficient to use an index vs scanning the entire table. If the collected statistics drift too far from reality, the query planner may make poor decisions. To avoid the risk, you can periodically `analyze` tables. + +```sql +analyze customers; +``` + +--- + +By following this guide, you'll be able to discern where indexes can optimize queries and enhance your PostgreSQL performance. Remember that each database is unique, so always consider the specific context and use case of your queries. + +export const Page = ({ children }) => + +export default Page From 511b5ec9773544eca35eb04799c72d846e069763 Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Mon, 7 Aug 2023 09:01:46 -0500 Subject: [PATCH 02/20] index-advisor error types --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index 8ba0e81140b..a21016ca8ba 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -136,7 +136,8 @@ from ## Limitations -Currently, index_advisor will only recommend single column, B-tree indexes. This restriction will be relaxed in future releases. +- index_advisor will only recommend single column, B-tree indexes. This restriction will be relaxed 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 uses of the generic argument e.g. `$1::int`. ## Resources From 4769f8b136bd3466eaf8776b63f0f84258ff3baf Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Mon, 7 Aug 2023 09:06:42 -0500 Subject: [PATCH 03/20] remove version from install instructions so latest is req --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index a21016ca8ba..40a9c661a43 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -26,8 +26,7 @@ Then, install index_advisor by running ```sql select dbdev.install('olirice-index_advisor'); create extension if not exists hypopg; -create extension "olirice-index_advisor" - version '0.1.0'; +create extension "olirice-index_advisor"; ``` ## API From f0934e17e18187f310c0d77d6c4303e0291b5b1a Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:23:56 +0200 Subject: [PATCH 04/20] Update apps/docs/pages/guides/database/extensions/index_advisor.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index 40a9c661a43..f2e2b18b0e4 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -73,7 +73,7 @@ from and will return a row recommending an index on the unindexed column. -More complex queries may generate additional suggested indexes +More complex queries may generate additional suggested indexes: ```sql create extension if not exists index_advisor cascade; From 393d7533af8280f67bb4c6419d5b86f0e42d69ec Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:24:03 +0200 Subject: [PATCH 05/20] Update apps/docs/pages/guides/database/extensions/index_advisor.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index f2e2b18b0e4..6d647b2341f 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -61,7 +61,7 @@ create table book( ); select - * + * from index_advisor('select book.id from book where title = $1'); From 24f186be2b84d5f5c8aa47553e71bafa891ca2e7 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:24:29 +0200 Subject: [PATCH 06/20] Update apps/docs/pages/guides/database/extensions/index_advisor.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index 6d647b2341f..635aa3c8df4 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -135,7 +135,7 @@ from ## Limitations -- index_advisor will only recommend single column, B-tree indexes. This restriction will be relaxed in future releases. +- 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 uses of the generic argument e.g. `$1::int`. ## Resources From 4c6ca9cc2c9bdc889e8b4228ce0f0ff20f20c898 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:24:43 +0200 Subject: [PATCH 07/20] Update apps/docs/pages/guides/database/extensions/index_advisor.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index 635aa3c8df4..f14467ab5ce 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -136,7 +136,7 @@ from ## Limitations - 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 uses of the generic argument e.g. `$1::int`. +- 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`. ## Resources From 581574bc580915c9d56f641091fea43efaf6b330 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:25:18 +0200 Subject: [PATCH 08/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index ecae3fc4559..3c547c51f3a 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -14,7 +14,7 @@ This guide is intended to: - help identify parts of a query that have the potential to be improved by indexes - introduce the most frequently applicable indexing tool -It is in no way comprehensive and should be thought of as a starting point on your optimization journey. +This is not a comprehensive resource, but rather a helpful starting point for your optimization journey. If you're new to query optimization, you may be interested in [index_advisor](/docs/guides/database/extensions/index_advisor), our tool for automatically detecting indexes that improve performance on a given query. From 38ae6fa00b6e023b2b6c8b62addb15797c0fc2ba Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:25:29 +0200 Subject: [PATCH 09/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index 3c547c51f3a..e85bb018e10 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -11,7 +11,7 @@ Aligning indexes with common query patterns can speed up data retrieval by order This guide is intended to: -- help identify parts of a query that have the potential to be improved by indexes +- help identify parts of a query that can benefit from indexes - introduce the most frequently applicable indexing tool This is not a comprehensive resource, but rather a helpful starting point for your optimization journey. From afaa8274a2fe032f8700de7fab6c9397f6b0abb6 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:25:42 +0200 Subject: [PATCH 10/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index e85bb018e10..57290d492bb 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -7,7 +7,7 @@ export const meta = { } When working with PostgreSQL, or any relational database, indexing is key to improving query performance. -Aligning indexes with common query patterns can speed up data retrieval by order of magnitude. +Aligning indexes with common query patterns can speed up data retrieval by an order of magnitude. This guide is intended to: From 54caab15af37312971cca389b5da6171718c4ff2 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:25:56 +0200 Subject: [PATCH 11/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index 57290d492bb..a1c92016527 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -38,7 +38,7 @@ order by limit 10 ``` -In this query, there are several parts indexes could likely help in optimizing the performance: +In this query, there are several parts that indexes could likely help in optimizing the performance: ### `where` Clause: From c0cf84e9e6fb2a2ff0af1e5efb90c9b47995a025 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:26:08 +0200 Subject: [PATCH 12/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index a1c92016527..6103f210990 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -90,7 +90,7 @@ explain select * from customers where sign_up_date > 25; ### Use Appropriate Index Types -PostgreSQL offers various index types like [B-tree, Hash, GIN, etc](https://www.postgresql.org/docs/current/indexes-types.html). Select the type that best suits your data and query pattern. Using the right index type can make a significant difference. For example, using a BRIN index on field that is always increasing on a table with infrequent updates, like `created_at` on an `orders` table, routinely results in indexes that are +10x smaller than the equivalent default B-tree index. That translates into better scalability. +PostgreSQL offers various index types like [B-tree, Hash, GIN, etc](https://www.postgresql.org/docs/current/indexes-types.html). Select the type that best suits your data and query pattern. Using the right index type can make a significant difference. For example, using a BRIN index on a field that always increases and lives within a table that updates infrequently - like `created_at` on an `orders` table - routinely results in indexes that are +10x smaller than the equivalent default B-tree index. That translates into better scalability. ```sql create index idx_orders_created_at ON customers using brin(created_at); From 16ba1a095a476051eaadf01fa62398cfd5335d43 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:26:21 +0200 Subject: [PATCH 13/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index 6103f210990..cd4d132d2a2 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -119,7 +119,7 @@ Avoid the urge to index columns you operate on infrequently. While indexes can s ### Statistics -Postgres maintains a set of statistics about the contents of your tables. Those statistics are used by the query planner to decide e.g. when its is more efficient to use an index vs scanning the entire table. If the collected statistics drift too far from reality, the query planner may make poor decisions. To avoid the risk, you can periodically `analyze` tables. +Postgres maintains a set of statistics about the contents of your tables. Those statistics are used by the query planner to decide when it's is more efficient to use an index vs scanning the entire table. If the collected statistics drift too far from reality, the query planner may make poor decisions. To avoid this risk, you can periodically `analyze` tables. ```sql analyze customers; From bb61e390918f59f9e303878f4d508b04cbc1b2e1 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:26:27 +0200 Subject: [PATCH 14/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index cd4d132d2a2..5c9ea348f73 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -115,7 +115,7 @@ create index idx_customers_sign_up_date_priority on customers (sign_up_date, pri ### Over-Indexing -Avoid the urge to index columns you operate on infrequently. While indexes can speed up reads, they also slow down writes, so its important to balance those factors when making indexing decisions. +Avoid the urge to index columns you operate on infrequently. While indexes can speed up reads, they also slow down writes, so it's important to balance those factors when making indexing decisions. ### Statistics From c243ed74d6306e978bf6b7d9349af3df918f7e20 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:26:43 +0200 Subject: [PATCH 15/20] Update apps/docs/pages/guides/database/query-optimization.mdx Co-authored-by: Greg Richardson --- apps/docs/pages/guides/database/query-optimization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index 5c9ea348f73..582ab02030a 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -107,7 +107,7 @@ where status = 'shipped'; ### Composite Indexes -If filtering or joining on multiple columns, a composite index can help postgres referring to multiple indexes to identify the relevant rows. +If filtering or joining on multiple columns, a composite index prevents Postgres from referring to multiple indexes when identifying the relevant rows. ```sql create index idx_customers_sign_up_date_priority on customers (sign_up_date, priority); From d956d45e3305c20fde7a34dd526ce2e373fca3bb Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Tue, 15 Aug 2023 09:59:53 -0500 Subject: [PATCH 16/20] revert extensions.mdx prettier unindent --- apps/docs/pages/guides/database/extensions.mdx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/docs/pages/guides/database/extensions.mdx b/apps/docs/pages/guides/database/extensions.mdx index 45b743ab41d..8b729b6ba73 100644 --- a/apps/docs/pages/guides/database/extensions.mdx +++ b/apps/docs/pages/guides/database/extensions.mdx @@ -1,10 +1,9 @@ import Layout from '~/layouts/DefaultGuideLayout' export const meta = { - -id: 'extensions', -title: 'Postgres Extensions Overview', -description: 'Using Postgres extensions.', + id: 'extensions', + title: 'Postgres Extensions Overview', + description: 'Using Postgres extensions.', } Extensions are exactly as they sound - they "extend" the database with functionality which isn't part of the Postgres core. From 2b7df73c33245c52abbbfd5820b3b322c63986e0 Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Tue, 15 Aug 2023 10:03:14 -0500 Subject: [PATCH 17/20] add minimal example in header --- .../guides/database/extensions/index_advisor.mdx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index f14467ab5ce..92689e2d695 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -8,6 +8,22 @@ export const meta = { [Index advisor](https://github.com/supabase/index_advisor) is a Postgres extension for recommending indexes to improve query performance. + +For example: + +```sql +select + * +from + 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)"},| {} +(1 row) +``` + + Features: - Supports generic parameters e.g. `$1`, `$2` From f4d5f6c66227d51520411f460436c0ccc00be001 Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Tue, 15 Aug 2023 10:05:03 -0500 Subject: [PATCH 18/20] rephrase index-advisor intro --- apps/docs/pages/guides/database/query-optimization.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/docs/pages/guides/database/query-optimization.mdx b/apps/docs/pages/guides/database/query-optimization.mdx index 582ab02030a..3176c49adaf 100644 --- a/apps/docs/pages/guides/database/query-optimization.mdx +++ b/apps/docs/pages/guides/database/query-optimization.mdx @@ -11,8 +11,8 @@ Aligning indexes with common query patterns can speed up data retrieval by an or This guide is intended to: -- help identify parts of a query that can benefit from indexes -- introduce the most frequently applicable indexing tool +- help identify parts of a query that have the potential to be improved by indexes +- introduce tooling to help identify useful indexes This is not a comprehensive resource, but rather a helpful starting point for your optimization journey. From 42b9fd7375514e6502e263776bdef95f146c7ac1 Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Tue, 15 Aug 2023 10:14:30 -0500 Subject: [PATCH 19/20] add index_advisor to extension search --- apps/docs/data/extensions.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/docs/data/extensions.json b/apps/docs/data/extensions.json index 53c1c69b19e..96fb984b821 100644 --- a/apps/docs/data/extensions.json +++ b/apps/docs/data/extensions.json @@ -113,6 +113,12 @@ "tags": ["Admin", "Utility"], "link": "https://www.postgresql.org/docs/current/oldsnapshot.html" }, + { + "name": "index_advisor", + "comment": "optimize query performance with automatic index recommendation", + "tags": ["Utility"], + "link": "/guides/database/extensions/index_advisor" + }, { "name": "intarray", "comment": "functions, operators, and index support for 1-D arrays of integers", From 2a3ab25efba2da37bf97a3882e3dac7bd1dbffcf Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Tue, 15 Aug 2023 10:26:07 -0500 Subject: [PATCH 20/20] prettier fixes --- apps/docs/pages/guides/database/extensions/index_advisor.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/docs/pages/guides/database/extensions/index_advisor.mdx b/apps/docs/pages/guides/database/extensions/index_advisor.mdx index 92689e2d695..d155c36a49b 100644 --- a/apps/docs/pages/guides/database/extensions/index_advisor.mdx +++ b/apps/docs/pages/guides/database/extensions/index_advisor.mdx @@ -8,7 +8,6 @@ export const meta = { [Index advisor](https://github.com/supabase/index_advisor) is a Postgres extension for recommending indexes to improve query performance. - For example: ```sql @@ -23,7 +22,6 @@ from (1 row) ``` - Features: - Supports generic parameters e.g. `$1`, `$2`