mirror of
https://github.com/supabase/supabase.git
synced 2026-06-02 02:43:26 +08:00
Docs: explain() (#18886)
* direct copy from ChatGPT * add new menu item, clean up items * fix TOC video * fix formatting from GPT * Renaming the page - it should be more like a "job to be done" rather than "here is a specific function" * re-ordering the sections - get people using it first, then teach them the details * Adds the explain section to the docs
This commit is contained in:
@@ -791,15 +791,18 @@ export const api: NavMenuConstant = {
|
||||
name: 'Guides',
|
||||
url: '/guides/api',
|
||||
items: [
|
||||
{ name: 'Creating API routes', url: '/guides/api/creating-routes', items: [] },
|
||||
{ name: 'How API Keys work', url: '/guides/api/api-keys', items: [] },
|
||||
{ name: 'Securing your API', url: '/guides/api/securing-your-api', items: [] },
|
||||
{ name: 'Creating API routes', url: '/guides/api/creating-routes' },
|
||||
{ name: 'How API Keys work', url: '/guides/api/api-keys' },
|
||||
{ name: 'Securing your API', url: '/guides/api/securing-your-api' },
|
||||
{
|
||||
name: 'Debugging performance issues',
|
||||
url: '/guides/api/rest/debugging-performance',
|
||||
},
|
||||
{
|
||||
name: 'Querying joins and nested tables',
|
||||
url: '/guides/api/joins-and-nesting',
|
||||
items: [],
|
||||
},
|
||||
{ name: 'Using custom schemas', url: '/guides/api/using-custom-schemas', items: [] },
|
||||
{ name: 'Using custom schemas', url: '/guides/api/using-custom-schemas' },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
115
apps/docs/pages/guides/api/rest/debugging-performance.mdx
Normal file
115
apps/docs/pages/guides/api/rest/debugging-performance.mdx
Normal file
@@ -0,0 +1,115 @@
|
||||
import Layout from '~/layouts/DefaultGuideLayout'
|
||||
|
||||
export const meta = {
|
||||
id: 'debugging-performance',
|
||||
title: 'Debugging performance issues',
|
||||
description: 'Debug slow-running queries using the Postgres execution planner.',
|
||||
subtitle: 'Debug slow-running queries using the Postgres execution planner.',
|
||||
}
|
||||
|
||||
`explain()` is a method that provides the Postgres `EXPLAIN` execution plan of a query. It is a powerful tool for debugging slow queries and understanding how Postgres will execute a given query. This feature is applicable to any query, including those made through `rpc()` or write operations.
|
||||
|
||||
## Enabling `explain()`
|
||||
|
||||
`explain()` is disabled by default to protect sensitive information about your database structure and operations. We recommend using `explain()` in a non-production environment. Run the following SQL to enable `explain()`:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```sql
|
||||
-- enable explain
|
||||
alter role authenticator
|
||||
set pgrst.db_plan_enabled to 'true';
|
||||
|
||||
-- reload the config
|
||||
notify pgrst, 'reload config';
|
||||
```
|
||||
|
||||
## Using `explain()`
|
||||
|
||||
To get the execution plan of a query, you can chain the `explain()` method to a Supabase query:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
const { data, error } = await supabase
|
||||
.from('countries')
|
||||
.select()
|
||||
.explain()
|
||||
```
|
||||
|
||||
### Example data
|
||||
|
||||
To illustrate, consider the following setup of a `countries` table:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```sql
|
||||
create table countries (
|
||||
id int8 primary key,
|
||||
name text
|
||||
);
|
||||
|
||||
insert into countries
|
||||
(id, name)
|
||||
values
|
||||
(1, 'Afghanistan'),
|
||||
(2, 'Albania'),
|
||||
(3, 'Algeria');
|
||||
```
|
||||
|
||||
### Expected response
|
||||
|
||||
The response would typically look like this:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```markdown
|
||||
Aggregate (cost=33.34..33.36 rows=1 width=112)
|
||||
-> Limit (cost=0.00..18.33 rows=1000 width=40)
|
||||
-> Seq Scan on countries (cost=0.00..22.00 rows=1200 width=40)
|
||||
```
|
||||
|
||||
By default, the execution plan is returned in TEXT format. However, you can also retrieve it as JSON by specifying the `format` parameter.
|
||||
|
||||
## Production use with pre-request protection
|
||||
|
||||
If you need to enable `explain()` in a production environment, ensure you protect your database by restricting access to the `explain()` feature. You can do so by using a pre-request function that filters requests based on the IP address:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```sql
|
||||
create or replace function filter_plan_requests()
|
||||
returns void as $$
|
||||
declare
|
||||
headers json := current_setting('request.headers', true)::json;
|
||||
client_ip text := coalesce(headers->>'cf-connecting-ip', '');
|
||||
accept text := coalesce(headers->>'accept', '');
|
||||
your_ip text := '123.123.123.123'; -- replace this with your IP
|
||||
begin
|
||||
if accept like 'application/vnd.pgrst.plan%' and client_ip != your_ip then
|
||||
raise insufficient_privilege using
|
||||
message = 'Not allowed to use application/vnd.pgrst.plan';
|
||||
end if;
|
||||
end; $$ language plpgsql;
|
||||
alter role authenticator set pgrst.db_pre_request to 'filter_plan_requests';
|
||||
notify pgrst, 'reload config';
|
||||
```
|
||||
|
||||
Replace `'123.123.123.123'` with your actual IP address.
|
||||
|
||||
## Disabling explain
|
||||
|
||||
To disable the `explain()` method after use, execute the following SQL commands:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```sql
|
||||
-- disable explain
|
||||
alter role authenticator
|
||||
set pgrst.db_plan_enabled to 'false';
|
||||
|
||||
-- if you used the above pre-request
|
||||
alter role authenticator
|
||||
set pgrst.db_pre_request to '';
|
||||
|
||||
-- reload the config
|
||||
notify pgrst, 'reload config';
|
||||
```
|
||||
|
||||
export const Page = ({ children }) => <Layout meta={meta} children={children} />
|
||||
|
||||
export default Page
|
||||
@@ -4,20 +4,12 @@ export const meta = {
|
||||
id: 'generating-types',
|
||||
title: 'Generating Types',
|
||||
description: 'How to generate types for your API and Supabase libraries.',
|
||||
video: 'https://www.youtube.com/v/7CqlTU9aOR4',
|
||||
subtitle: 'How to generate types for your API and Supabase libraries.',
|
||||
tocVideo: '/7CqlTU9aOR4',
|
||||
}
|
||||
|
||||
Supabase APIs are generated from your database, which means that we can use database introspection to generate type-safe API definitions.
|
||||
|
||||
<div className="video-container">
|
||||
<iframe
|
||||
src="https://www.youtube-nocookie.com/embed/7CqlTU9aOR4"
|
||||
frameBorder="1"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
</div>
|
||||
|
||||
## Generating types using Supabase CLI
|
||||
|
||||
The Supabase CLI is a single binary Go application that provides everything you need to setup a local development environment.
|
||||
|
||||
@@ -372,6 +372,14 @@
|
||||
"product": "database",
|
||||
"parent": "modifiers",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"id": "explain",
|
||||
"title": "Using explain",
|
||||
"slug": "explain",
|
||||
"product": "database",
|
||||
"parent": "modifiers",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4320,6 +4320,7 @@ functions:
|
||||
```
|
||||
hideCodeBlock: true
|
||||
isSpotlight: true
|
||||
|
||||
- id: csv
|
||||
$ref: '@supabase/postgrest-js.PostgrestTransformBuilder.csv'
|
||||
title: csv()
|
||||
@@ -4358,6 +4359,7 @@ functions:
|
||||
By default, the data is returned in JSON format, but can also be returned as Comma Separated Values.
|
||||
hideCodeBlock: true
|
||||
isSpotlight: true
|
||||
|
||||
- id: returns
|
||||
$ref: '@supabase/postgrest-js.PostgrestTransformBuilder.returns'
|
||||
title: returns()
|
||||
@@ -4378,55 +4380,17 @@ functions:
|
||||
hideCodeBlock: true
|
||||
isSpotlight: true
|
||||
|
||||
- id: using-explain
|
||||
- id: explain
|
||||
$ref: '@supabase/postgrest-js.PostgrestTransformBuilder.explain'
|
||||
title: Using Explain
|
||||
description: |
|
||||
For debugging slow queries, you can get the [PostgreSQL EXPLAIN execution plan](https://www.postgresql.org/docs/current/sql-explain.html) of a query
|
||||
For debugging slow queries, you can get the [Postgres `EXPLAIN` execution plan](https://www.postgresql.org/docs/current/sql-explain.html) of a query
|
||||
using the `explain()` method. This works on any query, even for `rpc()` or writes.
|
||||
|
||||
Explain is not enabled by default as it can reveal sensitive information about your database.
|
||||
It's best to only enable this for testing environments but if you wish to enable it for production you can provide additional protection by using a `pre-request` function.
|
||||
|
||||
To enable it:
|
||||
|
||||
```sql
|
||||
alter role authenticator set pgrst.db_plan_enabled to 'true';
|
||||
notify pgrst, 'reload config';
|
||||
```
|
||||
|
||||
To only allow `explain()` from a fixed IP address you can do the following. Use this if you plan on enabling `explain()` on a production environment.
|
||||
|
||||
```sql
|
||||
create or replace function filter_plan_requests()
|
||||
returns void as $$
|
||||
declare
|
||||
headers json := current_setting('request.headers', true)::json;
|
||||
client_ip text := coalesce(headers->>'cf-connecting-ip', '');
|
||||
accept text := coalesce(headers->>'accept', '');
|
||||
your_ip text := '123.123.123.123'; -- replace this by your ip
|
||||
begin
|
||||
if accept like 'application/vnd.pgrst.plan%' and client_ip != your_ip then
|
||||
raise insufficient_privilege using
|
||||
message = 'Not allowed to use application/vnd.pgrst.plan';
|
||||
end if;
|
||||
end; $$ language plpgsql;
|
||||
|
||||
alter role authenticator set pgrst.db_pre_request to 'filter_plan_requests';
|
||||
notify pgrst, 'reload config';
|
||||
```
|
||||
|
||||
Once you're done using `explain()`, you can disable it with:
|
||||
|
||||
```sql
|
||||
alter role authenticator set pgrst.db_plan_enabled to 'false';
|
||||
-- if you used the above pre-request
|
||||
alter role authenticator set pgrst.db_pre_request to '';
|
||||
|
||||
notify pgrst, 'reload config';
|
||||
```
|
||||
- id: explain
|
||||
$ref: '@supabase/postgrest-js.PostgrestTransformBuilder.explain'
|
||||
title: explain()
|
||||
Follow the [Performance Debugging Guide](/docs/guides/api/rest/debugging-performance) to enable the functionality on your project.
|
||||
examples:
|
||||
- id: get-execution-plan
|
||||
name: Get the execution plan
|
||||
|
||||
Reference in New Issue
Block a user