From ff659a90c6b35bd9346be3bc82ac89c549e92215 Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Thu, 2 Feb 2023 11:16:27 -0600 Subject: [PATCH 1/6] postgres extension: hypopg doc --- .../NavigationMenu.constants.ts | 5 + .../guides/database/extensions/hypopg.mdx | 128 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 apps/docs/pages/guides/database/extensions/hypopg.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 0a6b8d4e81a..524a305ffaa 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -388,6 +388,11 @@ export const database = { url: undefined, items: [ { name: 'Overview', url: '/guides/database/extensions', items: [] }, +{ + name: 'HypoPG: Hypothetical indexes', + url: '/guides/database/extensions/hypopg', + items: [], + }, { name: 'plv8: Javascript Language', url: '/guides/database/extensions/plv8', diff --git a/apps/docs/pages/guides/database/extensions/hypopg.mdx b/apps/docs/pages/guides/database/extensions/hypopg.mdx new file mode 100644 index 00000000000..6dc5bb3a3ca --- /dev/null +++ b/apps/docs/pages/guides/database/extensions/hypopg.mdx @@ -0,0 +1,128 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'hypopg', + title: 'HypoPG: Hypothetical indexes', + description: 'Quickly check if an index can be used without creating it.', +} + +`HypoPG` is PostgreSQL extension for creating hypothetical/virtual indexes. + +## Overview + +HypoPG allows users to rapidly create hypothetical/virtual indexes that have no resource cost (CPU, disk, memory) that are visible to the PostgreSQL query planner. +That allows users to quickly search for an index to improve a slow query without waiting for them to build. + +## Usage + +### Enable the extension + + + + +1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard. +2. Click on **Extensions** in the sidebar. +3. Search for "hypopg" and enable the extension. + + + + +```sql +-- Enable the "hypopg" extension +create extension hypopg with schema extensions; + +-- Disable the "hypopg" extension +drop extension if exists hypopg; +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + +### Speeding up a Query + +Given a table populated with some data and simple query to select from the table by id + +```sql +create table account ( + id int, + address text +); + +insert into account(id, address) +select + id, + id || ' main street' +from + generate_series(1, 10000) id; +``` + +we can generate an explain plan for a description of how the PostgreSQL query planner +intends to execute the query. + +```sql +explain +select + * +from + account +where + id = 1; + + QUERY PLAN +------------------------------------------------------- + Seq Scan on account (cost=0.00..180.00 rows=1 width=13) + Filter: (id = 1) +(2 rows) +``` + +Using HypoPG, we can create a hypothetical index on the `account(id)` column to check if it would be useful to the query planner and then re-run the explain plan. + +Note that the virtual indexes created by HypoPG are only visible in the PostgreSQL connection that they were created in. Supabase Studio connects to PostgreSQL through a connection pooler so the `hypopg_create_index` statement and the `explain` statement should be executed in a single query. + +```sql +select * from hypopg_create_index('create index on account(id)'); + +explain select * from account where id=1; + QUERY PLAN +------------------------------------------------------------------------------------ + Index Scan using <13504>btree_account_id on hypo (cost=0.29..8.30 rows=1 width=13) + Index Cond: (id = 1) +(2 rows) +``` + +The query plan has changed from a `Seq Scan` to an `Index Scan` using the newly created virtual index, so we may choose to create a real version of the index with: + +```sql +create index on account(id); +``` + +to improve performance on the target query. + + +API: + +- [`hypo_create_index(text)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#create-a-hypothetical-index): A function to create a hypothetical index +- [`hypopg_list_indexes`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A View that lists all hypothetical indexes that have been created +- [`hypopg()`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function that lists all hypothetical indexes that have been created with the same format as pg_index +- [`hypopg_get_index_def(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to display the `create index` statement that would create the index +- [`hypopg_get_relation_size(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to estimate how large a hypothetical index would be +- [`hypopg_drop_index(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to remove a given hypothetical index by oid +- [`hypopg_reset()`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to remove all hypothetical indexes + +## Resources + +- Official [`HypoPG` documentation](https://hypopg.readthedocs.io/en/rel1_stable/) + +export const Page = ({ children }) => + +export default Page From 4e6e760112e6710f091bf7fc2f1b4dfd6e45e8dc Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Thu, 2 Feb 2023 12:47:31 -0600 Subject: [PATCH 2/6] postgres extension: pgroonga doc --- .../NavigationMenu.constants.ts | 7 +- .../guides/database/extensions/pgroonga.mdx | 113 ++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 apps/docs/pages/guides/database/extensions/pgroonga.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 524a305ffaa..9ee08b53777 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -388,7 +388,7 @@ export const database = { url: undefined, items: [ { name: 'Overview', url: '/guides/database/extensions', items: [] }, -{ + { name: 'HypoPG: Hypothetical indexes', url: '/guides/database/extensions/hypopg', items: [], @@ -399,6 +399,11 @@ export const database = { items: [], }, { name: 'http: RESTful Client', url: '/guides/database/extensions/http', items: [] }, + { + name: 'PGRoonga: Multilingual Full Text Search', + url: '/guides/database/extensions/pgroonga', + items: [], + }, { name: 'pg_cron: Job Scheduling', url: '/guides/database/extensions/pgcron', diff --git a/apps/docs/pages/guides/database/extensions/pgroonga.mdx b/apps/docs/pages/guides/database/extensions/pgroonga.mdx new file mode 100644 index 00000000000..0b8b480bf08 --- /dev/null +++ b/apps/docs/pages/guides/database/extensions/pgroonga.mdx @@ -0,0 +1,113 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'pgroonga', + title: 'PGRoonga: Multilingual Full Text Search', + description: 'Full Text Search for multiple languages in PostgreSQL', +} + +`PGroonga` is a PostgreSQL extension adding a full text search indexing method based on [Groonga](https://groonga.org). While native PostgreSQL supports full text indexing, it is limited to alphabet and digit based languages. `PGroonga` offers a wider range of character support making it viable for a superset of languages supported by PostgreSQL including Japanese, Chinese, etc. + +## Usage + +### Enable the extension + + + + +1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard. +2. Click on **Extensions** in the sidebar. +3. Search for "pgroonga" and enable the extension. + + + + +```sql +-- Enable the "pgroonga" extension +create extension pgroonga with schema extensions; + +-- Disable the "pgroonga" extension +drop extension if exists pgroonga; +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + +### Creating a Full Text Search Index + +Given a table with a `text` column + +```sql +create table memos ( + id serial primary key, + content text +); +``` + +We can index the column for full text search with a `pgroonga` index + +```sql +create index ix_memos_content ON memos USING pgroonga(content); +``` + +To test the full text index, we'll add some data. + +```sql +insert into memos(content) +values + ('PostgreSQL is a relational database management system.'), + ('Groonga is a fast full text search engine that supports all languages.'), + ('PGroonga is a PostgreSQL extension that uses Groonga as index.'), + ('There is groonga command.'); +``` + +The PostgreSQL query planner is smart enough to know that, for extremely small tables, its faster to scan the whole table rather than loading an index. To force the index to be used, we can disable sequential scans + +```sql +-- For testing only. Don't do this in production +set enable_seqscan = off; +``` + +Now if we run an explain plan on a query filtering on `memos.content`, + +```sql +explain +select + * +from + memos +where + content like '%engine%'; + + QUERY PLAN +----------------------------------------------------------------------------- +Index Scan using ix_memos_content on memos (cost=0.00..1.11 rows=1 width=36) + Index Cond: (content ~~ '%engine%'::text) +(2 rows) +``` + +The pgroonga index is used to retrive the result set + +```markdown +| id | content | +| -- | ------------------------------------------------------------------------ | +| 2 | 'Groonga is a fast full text search engine that supports all languages.' | +``` + +## Resources + +- Official [`PGroonga` documentation](https://pgroonga.github.io/tutorial/) + +export const Page = ({ children }) => + +export default Page From eddb758d4257aa29e6dbe2aeaddbbc373ef8406b Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Thu, 2 Feb 2023 14:00:17 -0600 Subject: [PATCH 3/6] postgres extension: pg_stat_statements doc --- .../NavigationMenu.constants.ts | 5 + .../extensions/pg_stat_statements.mdx | 99 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 9ee08b53777..aa25744b65f 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -414,6 +414,11 @@ export const database = { url: '/guides/database/extensions/pgnet', items: [], }, + { + name: 'pg_stat_statements: SQL Planning and Execution Statistics', + url: '/guides/database/extensions/pg_stat_statements', + items: [], + }, { name: 'PostGIS: Geo queries', url: '/guides/database/extensions/postgis', diff --git a/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx b/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx new file mode 100644 index 00000000000..a8831f44b81 --- /dev/null +++ b/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx @@ -0,0 +1,99 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'pg_stat_statements', + title: 'pg_stat_statements: SQL Planning and Execution Statistics', + description: 'Track planning and execution statistics of all SQL statements executed on the database.', +} + +`pg_stat_statements` is a database extension for tracking planning and execution statistics about all SQL statements executed on the database. + +## Overview + +`pg_stat_statements` exposes a view, of the same name, that tracks statistics about SQL statements executed on the database. The following table shows some of the available statistics and metadata: + +```markdown + +| Column Type | Description | +|-------------|-------------| +| userid oid (references pg_authid.oid) | OID of user who executed the statement | +| dbid oid (references pg_database.oid) | OID of database in which the statement was executed | +| toplevel bool | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) | +| queryid bigint | Hash code to identify identical normalized queries. | +| query text | Text of a representative statement | +| plans bigint | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) | +| total_plan_time double precision +| Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) | +| min_plan_time double precision | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) | +| ... | ... | +``` +A full list of statistics is available in the [`pg_stat_statements` docs](https://www.postgresql.org/docs/current/pgstatstatements.html) + + +## Usage + +### Enable the extension + + + + +1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard. +2. Click on **Extensions** in the sidebar. +3. Search for "pg_stat_statements" and enable the extension. + + + + +```sql +-- Enable the "pg_stat_statements" extension +create extension pg_stat_statements with schema extensions; + +-- Disable the "pg_stat_statements" extension +drop extension if exists pg_stat_statements; +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + +### Inspecting Activity + +A common use for `pg_stat_statements` is to track down expensive or slow queries. The `pg_stat_statements` view contains a row for each executed query with statistics inlined. You can leverage the statistics to, for example, identify frequently executed and slow queries against a given table + +```sql +select + calls, + mean_exec_time, + max_exec_time, + total_exec_time, + stddev_exec_time, + query, +from + pg_stat_statements +where + calls > 1000 -- at least 50 calls + and mean_exec_time > 2.0 -- averaging at least 2ms/call + and total_exec_time > 60000 -- at least one minute total server time spent + and query ilike '%user_in_organization%' -- filter to queries that touch the user_in_organization table +order by + calls desc +``` + +From the results, an informed decision about which queries to optimize/index/adjust can be made. + +## Resources + +- Official [`pg_stat_statements` documentation](https://www.postgresql.org/docs/current/pgstatstatements.html) + +export const Page = ({ children }) => + +export default Page From 23bf8b9f8279df2e804b19a04594c9effd1f1834 Mon Sep 17 00:00:00 2001 From: Oliver Rice Date: Thu, 2 Feb 2023 15:04:15 -0600 Subject: [PATCH 4/6] postgres extension: pg_jsonschema doc --- .../NavigationMenu.constants.ts | 5 + .../database/extensions/pg_jsonschema.mdx | 114 ++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index aa25744b65f..e939cafa4b4 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -409,6 +409,11 @@ export const database = { url: '/guides/database/extensions/pgcron', items: [], }, + { + name: 'pg_jsonschema: JSON Schema Validation', + url: '/guides/database/extensions/pg_jsonschema', + items: [], + }, { name: 'pg_net: Async Networking', url: '/guides/database/extensions/pgnet', diff --git a/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx b/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx new file mode 100644 index 00000000000..bfe71f75a46 --- /dev/null +++ b/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx @@ -0,0 +1,114 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'pg_jsonschema', + title: 'pg_jsonschema: JSON Schema Validation', + description: 'Validate json/jsonb with JSON Schema in PostgreSQL.', +} + +[`pg_jsonschema`](https://json-schema.org) is a PostgreSQL extension adding support for JSON schema validation on json and jsonb data types. + +## Overview + +[JSON Schema](https://json-schema.org) is a language for annotating and validating JSON documents. `pg_jsonschema` adds the ability to validate PostgreSQL's builtin `json` and `jsonb` data types against a JSON Schema document. + +## Usage + +### Enable the extension + + + + +1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard. +2. Click on **Extensions** in the sidebar. +3. Search for "pg_jsonschema" and enable the extension. + + + + +```sql +-- Enable the "pg_jsonschema" extension +create extension pg_jsonschema with schema extensions; + +-- Disable the "pg_jsonschema" extension +drop extension if exists pg_jsonschema; +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + +API: + +- [`json_matches_schema(schema json, instance json)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `json` *instance* conforms to a JSON Schema *schema*. +- [`jsonb_matches_schema(schema json, instance jsonb)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `jsonb` *instance* conforms to a JSON Schema *schema*. + +### Validating a Document + +Since `pg_jsonschema` exposes its utilities as functions, we can test it with a simple select statement + +```sql +select + extensions.json_matches_schema( + schema := '{"type": "object"}', + instance := '{}' + ); +``` + +`pg_jsonschema` is generally used in tandem with a [check constraint](https://www.postgresql.org/docs/current/ddl-constraints.html) as a way to constrain the contents of a json/b field to match a JSON Schema. + +```sql +create table customer( + id serial primary key, + ... + metadata json, + + check ( + json_matches_schema( + '{ + "type": "object", + "properties": { + "tags": { + "type": "array", + "items": { + "type": "string", + "maxLength": 16 + } + } + } + }', + metadata + ) + ) +); + +-- Example: Valid Payload +insert into customer(metadata) +values ('{"tags": ["vip", "darkmode-ui"]}'); +-- Result: +-- INSERT 0 1 + +-- Example: Invalid Payload +insert into customer(metadata) +values ('{"tags": [1, 3]}'); +-- Result: +-- ERROR: new row for relation "customer" violates check constraint "customer_metadata_check" +-- DETAIL: Failing row contains (2, {"tags": [1, 3]}). +``` + +## Resources + +- Official [`pg_jsonschema` documentation](https://github.com/supabase/pg_jsonschema) + +export const Page = ({ children }) => + +export default Page From 4e0092cd7be187eb7dd87617ff71f079253dad57 Mon Sep 17 00:00:00 2001 From: dannykng Date: Thu, 2 Feb 2023 15:42:13 -0800 Subject: [PATCH 5/6] Copy edits --- .../guides/database/extensions/hypopg.mdx | 50 +++++++------------ .../database/extensions/pg_jsonschema.mdx | 16 +++--- .../extensions/pg_stat_statements.mdx | 44 +++++++--------- .../guides/database/extensions/pgroonga.mdx | 28 ++++------- 4 files changed, 54 insertions(+), 84 deletions(-) diff --git a/apps/docs/pages/guides/database/extensions/hypopg.mdx b/apps/docs/pages/guides/database/extensions/hypopg.mdx index 6dc5bb3a3ca..cfedd145e07 100644 --- a/apps/docs/pages/guides/database/extensions/hypopg.mdx +++ b/apps/docs/pages/guides/database/extensions/hypopg.mdx @@ -6,11 +6,7 @@ export const meta = { description: 'Quickly check if an index can be used without creating it.', } -`HypoPG` is PostgreSQL extension for creating hypothetical/virtual indexes. - -## Overview - -HypoPG allows users to rapidly create hypothetical/virtual indexes that have no resource cost (CPU, disk, memory) that are visible to the PostgreSQL query planner. +`HypoPG` is PostgreSQL extension for creating hypothetical/virtual indexes. HypoPG allows users to rapidly create hypothetical/virtual indexes that have no resource cost (CPU, disk, memory) that are visible to the PostgreSQL query planner. That allows users to quickly search for an index to improve a slow query without waiting for them to build. ## Usage @@ -48,9 +44,9 @@ It's good practice to create the extension within a separate schema (like `exten -### Speeding up a Query +### Speeding up a query -Given a table populated with some data and simple query to select from the table by id +Given the following table and a simple query to select from the table by id: ```sql create table account ( @@ -66,17 +62,11 @@ from generate_series(1, 10000) id; ``` -we can generate an explain plan for a description of how the PostgreSQL query planner -intends to execute the query. +We can generate an explain plan for a description of how the PostgreSQL query planner +intends to execute the query. ```sql -explain -select - * -from - account -where - id = 1; +explain select * from account where id=1; QUERY PLAN ------------------------------------------------------- @@ -85,14 +75,15 @@ where (2 rows) ``` -Using HypoPG, we can create a hypothetical index on the `account(id)` column to check if it would be useful to the query planner and then re-run the explain plan. +Using HypoPG, we can create a hypothetical index on the `account(id)` column to check if it would be useful to the query planner and then re-run the explain plan. -Note that the virtual indexes created by HypoPG are only visible in the PostgreSQL connection that they were created in. Supabase Studio connects to PostgreSQL through a connection pooler so the `hypopg_create_index` statement and the `explain` statement should be executed in a single query. +Note that the virtual indexes created by HypoPG are only visible in the PostgreSQL connection that they were created in. Supabase connects to PostgreSQL through a connection pooler so the `hypopg_create_index` statement and the `explain` statement should be executed in a single query. ```sql select * from hypopg_create_index('create index on account(id)'); explain select * from account where id=1; + QUERY PLAN ------------------------------------------------------------------------------------ Index Scan using <13504>btree_account_id on hypo (cost=0.29..8.30 rows=1 width=13) @@ -100,28 +91,25 @@ explain select * from account where id=1; (2 rows) ``` -The query plan has changed from a `Seq Scan` to an `Index Scan` using the newly created virtual index, so we may choose to create a real version of the index with: +The query plan has changed from a `Seq Scan` to an `Index Scan` using the newly created virtual index, so we may choose to create a real version of the index to improve performance on the target query: ```sql create index on account(id); ``` -to improve performance on the target query. +## Functions - -API: - -- [`hypo_create_index(text)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#create-a-hypothetical-index): A function to create a hypothetical index -- [`hypopg_list_indexes`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A View that lists all hypothetical indexes that have been created -- [`hypopg()`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function that lists all hypothetical indexes that have been created with the same format as pg_index -- [`hypopg_get_index_def(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to display the `create index` statement that would create the index -- [`hypopg_get_relation_size(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to estimate how large a hypothetical index would be -- [`hypopg_drop_index(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to remove a given hypothetical index by oid -- [`hypopg_reset()`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to remove all hypothetical indexes +- [`hypo_create_index(text)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#create-a-hypothetical-index): A function to create a hypothetical index. +- [`hypopg_list_indexes`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A View that lists all hypothetical indexes that have been created. +- [`hypopg()`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function that lists all hypothetical indexes that have been created with the same format as pg_index. +- [`hypopg_get_index_def(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to display the `create index` statement that would create the index. +- [`hypopg_get_relation_size(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to estimate how large a hypothetical index would be. +- [`hypopg_drop_index(oid)`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to remove a given hypothetical index by oid. +- [`hypopg_reset()`](https://hypopg.readthedocs.io/en/rel1_stable/usage.html#manipulate-hypothetical-indexes): A function to remove all hypothetical indexes. ## Resources -- Official [`HypoPG` documentation](https://hypopg.readthedocs.io/en/rel1_stable/) +- Official [HypoPG documentation](https://hypopg.readthedocs.io/en/rel1_stable/) export const Page = ({ children }) => diff --git a/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx b/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx index bfe71f75a46..2f4776afea2 100644 --- a/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx +++ b/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx @@ -6,11 +6,7 @@ export const meta = { description: 'Validate json/jsonb with JSON Schema in PostgreSQL.', } -[`pg_jsonschema`](https://json-schema.org) is a PostgreSQL extension adding support for JSON schema validation on json and jsonb data types. - -## Overview - -[JSON Schema](https://json-schema.org) is a language for annotating and validating JSON documents. `pg_jsonschema` adds the ability to validate PostgreSQL's builtin `json` and `jsonb` data types against a JSON Schema document. +[JSON Schema](https://json-schema.org) is a language for annotating and validating JSON documents. [`pg_jsonschema`](https://json-schema.org) is a PostgreSQL extension that adds the ability to validate PostgreSQL's built-in `json` and `jsonb` data types against a JSON Schema document. ## Usage @@ -47,14 +43,14 @@ It's good practice to create the extension within a separate schema (like `exten -API: +## Functions -- [`json_matches_schema(schema json, instance json)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `json` *instance* conforms to a JSON Schema *schema*. -- [`jsonb_matches_schema(schema json, instance jsonb)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `jsonb` *instance* conforms to a JSON Schema *schema*. +- [`json_matches_schema(schema json, instance json)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `json` _instance_ conforms to a JSON Schema _schema_. +- [`jsonb_matches_schema(schema json, instance jsonb)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `jsonb` _instance_ conforms to a JSON Schema _schema_. -### Validating a Document +### Validating a document -Since `pg_jsonschema` exposes its utilities as functions, we can test it with a simple select statement +Since `pg_jsonschema` exposes its utilities as functions, we can test it with a simple select statement: ```sql select diff --git a/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx b/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx index a8831f44b81..48e9e757f28 100644 --- a/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx +++ b/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx @@ -3,32 +3,24 @@ import Layout from '~/layouts/DefaultGuideLayout' export const meta = { id: 'pg_stat_statements', title: 'pg_stat_statements: SQL Planning and Execution Statistics', - description: 'Track planning and execution statistics of all SQL statements executed on the database.', + description: + 'Track planning and execution statistics of all SQL statements executed on the database.', } -`pg_stat_statements` is a database extension for tracking planning and execution statistics about all SQL statements executed on the database. +`pg_stat_statements` is a database extension that exposes a view, of the same name, to track statistics about SQL statements executed on the database. The following table shows some of the available statistics and metadata: -## Overview - -`pg_stat_statements` exposes a view, of the same name, that tracks statistics about SQL statements executed on the database. The following table shows some of the available statistics and metadata: - -```markdown - -| Column Type | Description | -|-------------|-------------| -| userid oid (references pg_authid.oid) | OID of user who executed the statement | -| dbid oid (references pg_database.oid) | OID of database in which the statement was executed | -| toplevel bool | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) | -| queryid bigint | Hash code to identify identical normalized queries. | -| query text | Text of a representative statement | -| plans bigint | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) | -| total_plan_time double precision -| Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) | -| min_plan_time double precision | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) | -| ... | ... | -``` -A full list of statistics is available in the [`pg_stat_statements` docs](https://www.postgresql.org/docs/current/pgstatstatements.html) +| Column Type | Description | +| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| userid oid (references pg_authid.oid) | OID of user who executed the statement | +| dbid oid (references pg_database.oid) | OID of database in which the statement was executed | +| toplevel bool | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) | +| queryid bigint | Hash code to identify identical normalized queries. | +| query text | Text of a representative statement | +| plans bigint | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) | +| total_plan_time double precision | Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) | +| min_plan_time double precision | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) | +A full list of statistics is available in the [pg_stat_statements docs](https://www.postgresql.org/docs/current/pgstatstatements.html). ## Usage @@ -65,9 +57,9 @@ It's good practice to create the extension within a separate schema (like `exten -### Inspecting Activity +### Inspecting activity -A common use for `pg_stat_statements` is to track down expensive or slow queries. The `pg_stat_statements` view contains a row for each executed query with statistics inlined. You can leverage the statistics to, for example, identify frequently executed and slow queries against a given table +A common use for `pg_stat_statements` is to track down expensive or slow queries. The `pg_stat_statements` view contains a row for each executed query with statistics inlined. For example, you can leverage the statistics to identify frequently executed and slow queries against a given table. ```sql select @@ -88,11 +80,11 @@ order by calls desc ``` -From the results, an informed decision about which queries to optimize/index/adjust can be made. +From the results, an informed decision about which queries to optimize, index, or adjust can be made. ## Resources -- Official [`pg_stat_statements` documentation](https://www.postgresql.org/docs/current/pgstatstatements.html) +- Official [pg_stat_statements documentation](https://www.postgresql.org/docs/current/pgstatstatements.html) export const Page = ({ children }) => diff --git a/apps/docs/pages/guides/database/extensions/pgroonga.mdx b/apps/docs/pages/guides/database/extensions/pgroonga.mdx index 0b8b480bf08..858101ef2b7 100644 --- a/apps/docs/pages/guides/database/extensions/pgroonga.mdx +++ b/apps/docs/pages/guides/database/extensions/pgroonga.mdx @@ -43,9 +43,9 @@ It's good practice to create the extension within a separate schema (like `exten -### Creating a Full Text Search Index +### Creating a full text search index -Given a table with a `text` column +Given a table with a `text` column: ```sql create table memos ( @@ -54,7 +54,7 @@ create table memos ( ); ``` -We can index the column for full text search with a `pgroonga` index +We can index the column for full text search with a `pgroonga` index: ```sql create index ix_memos_content ON memos USING pgroonga(content); @@ -71,23 +71,17 @@ values ('There is groonga command.'); ``` -The PostgreSQL query planner is smart enough to know that, for extremely small tables, its faster to scan the whole table rather than loading an index. To force the index to be used, we can disable sequential scans +The PostgreSQL query planner is smart enough to know that, for extremely small tables, it's faster to scan the whole table rather than loading an index. To force the index to be used, we can disable sequential scans: ```sql -- For testing only. Don't do this in production set enable_seqscan = off; ``` -Now if we run an explain plan on a query filtering on `memos.content`, +Now if we run an explain plan on a query filtering on `memos.content`: ```sql -explain -select - * -from - memos -where - content like '%engine%'; +explain select * from memos where content like '%engine%'; QUERY PLAN ----------------------------------------------------------------------------- @@ -96,17 +90,17 @@ Index Scan using ix_memos_content on memos (cost=0.00..1.11 rows=1 width=36) (2 rows) ``` -The pgroonga index is used to retrive the result set +The pgroonga index is used to retrive the result set: ```markdown -| id | content | -| -- | ------------------------------------------------------------------------ | -| 2 | 'Groonga is a fast full text search engine that supports all languages.' | +| id | content | +| --- | ------------------------------------------------------------------------ | +| 2 | 'Groonga is a fast full text search engine that supports all languages.' | ``` ## Resources -- Official [`PGroonga` documentation](https://pgroonga.github.io/tutorial/) +- Official [PGroonga documentation](https://pgroonga.github.io/tutorial/) export const Page = ({ children }) => From 305c62a83e8f50f4f8498cb6564f815bcf6b7b85 Mon Sep 17 00:00:00 2001 From: dannykng Date: Thu, 2 Feb 2023 16:02:29 -0800 Subject: [PATCH 6/6] Ignore Prettier for SQL code blocks --- apps/docs/pages/guides/database/extensions/hypopg.mdx | 5 +++++ .../docs/pages/guides/database/extensions/pg_jsonschema.mdx | 3 +++ .../pages/guides/database/extensions/pg_stat_statements.mdx | 2 ++ apps/docs/pages/guides/database/extensions/pgroonga.mdx | 6 ++++++ 4 files changed, 16 insertions(+) diff --git a/apps/docs/pages/guides/database/extensions/hypopg.mdx b/apps/docs/pages/guides/database/extensions/hypopg.mdx index cfedd145e07..c493f9f89cd 100644 --- a/apps/docs/pages/guides/database/extensions/hypopg.mdx +++ b/apps/docs/pages/guides/database/extensions/hypopg.mdx @@ -28,6 +28,7 @@ That allows users to quickly search for an index to improve a slow query without +{/* prettier-ignore */} ```sql -- Enable the "hypopg" extension create extension hypopg with schema extensions; @@ -48,6 +49,7 @@ It's good practice to create the extension within a separate schema (like `exten Given the following table and a simple query to select from the table by id: +{/* prettier-ignore */} ```sql create table account ( id int, @@ -65,6 +67,7 @@ from We can generate an explain plan for a description of how the PostgreSQL query planner intends to execute the query. +{/* prettier-ignore */} ```sql explain select * from account where id=1; @@ -79,6 +82,7 @@ Using HypoPG, we can create a hypothetical index on the `account(id)` column to Note that the virtual indexes created by HypoPG are only visible in the PostgreSQL connection that they were created in. Supabase connects to PostgreSQL through a connection pooler so the `hypopg_create_index` statement and the `explain` statement should be executed in a single query. +{/* prettier-ignore */} ```sql select * from hypopg_create_index('create index on account(id)'); @@ -93,6 +97,7 @@ explain select * from account where id=1; The query plan has changed from a `Seq Scan` to an `Index Scan` using the newly created virtual index, so we may choose to create a real version of the index to improve performance on the target query: +{/* prettier-ignore */} ```sql create index on account(id); ``` diff --git a/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx b/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx index 2f4776afea2..c51a4c3783e 100644 --- a/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx +++ b/apps/docs/pages/guides/database/extensions/pg_jsonschema.mdx @@ -27,6 +27,7 @@ export const meta = { +{/* prettier-ignore */} ```sql -- Enable the "pg_jsonschema" extension create extension pg_jsonschema with schema extensions; @@ -52,6 +53,7 @@ It's good practice to create the extension within a separate schema (like `exten Since `pg_jsonschema` exposes its utilities as functions, we can test it with a simple select statement: +{/* prettier-ignore */} ```sql select extensions.json_matches_schema( @@ -62,6 +64,7 @@ select `pg_jsonschema` is generally used in tandem with a [check constraint](https://www.postgresql.org/docs/current/ddl-constraints.html) as a way to constrain the contents of a json/b field to match a JSON Schema. +{/* prettier-ignore */} ```sql create table customer( id serial primary key, diff --git a/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx b/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx index 48e9e757f28..711878d78c0 100644 --- a/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx +++ b/apps/docs/pages/guides/database/extensions/pg_stat_statements.mdx @@ -41,6 +41,7 @@ A full list of statistics is available in the [pg_stat_statements docs](https:// +{/* prettier-ignore */} ```sql -- Enable the "pg_stat_statements" extension create extension pg_stat_statements with schema extensions; @@ -61,6 +62,7 @@ It's good practice to create the extension within a separate schema (like `exten A common use for `pg_stat_statements` is to track down expensive or slow queries. The `pg_stat_statements` view contains a row for each executed query with statistics inlined. For example, you can leverage the statistics to identify frequently executed and slow queries against a given table. +{/* prettier-ignore */} ```sql select calls, diff --git a/apps/docs/pages/guides/database/extensions/pgroonga.mdx b/apps/docs/pages/guides/database/extensions/pgroonga.mdx index 858101ef2b7..f006857303c 100644 --- a/apps/docs/pages/guides/database/extensions/pgroonga.mdx +++ b/apps/docs/pages/guides/database/extensions/pgroonga.mdx @@ -27,6 +27,7 @@ export const meta = { +{/* prettier-ignore */} ```sql -- Enable the "pgroonga" extension create extension pgroonga with schema extensions; @@ -47,6 +48,7 @@ It's good practice to create the extension within a separate schema (like `exten Given a table with a `text` column: +{/* prettier-ignore */} ```sql create table memos ( id serial primary key, @@ -56,12 +58,14 @@ create table memos ( We can index the column for full text search with a `pgroonga` index: +{/* prettier-ignore */} ```sql create index ix_memos_content ON memos USING pgroonga(content); ``` To test the full text index, we'll add some data. +{/* prettier-ignore */} ```sql insert into memos(content) values @@ -73,6 +77,7 @@ values The PostgreSQL query planner is smart enough to know that, for extremely small tables, it's faster to scan the whole table rather than loading an index. To force the index to be used, we can disable sequential scans: +{/* prettier-ignore */} ```sql -- For testing only. Don't do this in production set enable_seqscan = off; @@ -80,6 +85,7 @@ set enable_seqscan = off; Now if we run an explain plan on a query filtering on `memos.content`: +{/* prettier-ignore */} ```sql explain select * from memos where content like '%engine%';