Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add optimize docs #6159

Merged
merged 74 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
b0d0621
feat: add optimize to the sidebar
ankur-arch Jul 22, 2024
6ad6b78
feat: add optimize in the getting started section
ankur-arch Jul 22, 2024
d1035a4
fix: add optimize url
ankur-arch Jul 22, 2024
c8b8f6a
feat: add optimize docs
ankur-arch Jul 22, 2024
49fd29e
fix: add optimize icons
ankur-arch Jul 25, 2024
0408abe
feat: add more sections to optmize docs
ankur-arch Jul 25, 2024
b5cbec8
feat: add optimize to footer
ankur-arch Jul 25, 2024
1258dda
feat: add note on using optimize
ankur-arch Jul 25, 2024
8f35f27
fix: correct spelling for usecase
ankur-arch Jul 25, 2024
19fd3ac
feat: add more on indexes
ankur-arch Jul 25, 2024
1c8969e
Merge branch 'main' into optimize-docs
carlagn Aug 12, 2024
ed9401b
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
5342d35
Update content/700-optimize/400-recommendations.mdx
ankur-arch Aug 13, 2024
acb1e7e
Update content/700-optimize/400-recommendations.mdx
ankur-arch Aug 13, 2024
b9d9ac9
Update content/700-optimize/400-recommendations.mdx
ankur-arch Aug 13, 2024
3447227
Update content/700-optimize/400-recommendations.mdx
ankur-arch Aug 13, 2024
fe9229c
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
2ecc73e
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
0696c55
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
426af9a
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
248fa27
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
8ef853f
Merge branch 'main' into optimize-docs
ankur-arch Aug 13, 2024
4fa870b
feat: add enhancements on recommendations
ankur-arch Aug 13, 2024
9676e16
Update content/700-optimize/200-getting-started.mdx
ankur-arch Aug 13, 2024
bf8d19f
Update content/700-optimize/300-recording.mdx
ankur-arch Aug 13, 2024
9ca80d5
Update content/700-optimize/300-recording.mdx
ankur-arch Aug 13, 2024
d53f231
fix: rename file to recordings
ankur-arch Aug 13, 2024
ca12e21
Update ormLinkSectionWrapper
carlagn Aug 13, 2024
983b46e
Merge branch 'main' into optimize-docs
ankur-arch Aug 19, 2024
ae25dd8
feat: add ai explainer section to the docs
ankur-arch Aug 19, 2024
4d8554f
feat: add ai limitations for optimize
ankur-arch Aug 19, 2024
43d9b05
feat: add more faq items
ankur-arch Aug 19, 2024
17da7c2
Merge branch 'main' into optimize-docs
ankur-arch Aug 20, 2024
2675a83
feat: new content changes
ankur-arch Aug 21, 2024
c856ea6
fix: remove random line
ankur-arch Aug 21, 2024
ddc8b7d
fix: optimize api key section
ankur-arch Aug 21, 2024
282ee28
feat: improve getting started section
ankur-arch Aug 21, 2024
48239a8
fix: add more feedback
ankur-arch Aug 21, 2024
4722a74
fix: broken link on ai-explainer
ankur-arch Aug 21, 2024
e62d472
Merge branch 'main' into optimize-docs
ankur-arch Aug 21, 2024
5eda3a7
feat: add ms sql server to optimize
ankur-arch Aug 22, 2024
81df09f
feat: update optimize url
ankur-arch Sep 5, 2024
a3df33a
Merge branch 'main' into optimize-docs
ankur-arch Sep 5, 2024
ff6dfb5
feat: update API key getting steps
ankur-arch Sep 5, 2024
f2bbb8f
Update content/700-optimize/200-getting-started.mdx
ankur-arch Sep 6, 2024
eb4b8ce
Update content/100-getting-started/index.mdx
ankur-arch Sep 6, 2024
5b3dfa0
Update content/100-getting-started/index.mdx
ankur-arch Sep 6, 2024
9da0c0f
Update content/700-optimize/index.mdx
ankur-arch Sep 8, 2024
45d7758
Update content/700-optimize/200-getting-started.mdx
ankur-arch Sep 8, 2024
87cf0b0
feat: move optimize
ankur-arch Sep 8, 2024
23b04a2
Merge branch 'main' into optimize-docs
ankur-arch Sep 8, 2024
641c1fa
fix: replace to prisma ai
ankur-arch Sep 8, 2024
cb5e436
fix: paraphrase to be more accurate
ankur-arch Sep 8, 2024
b53a0db
fix: clear recommendations page
ankur-arch Sep 8, 2024
8fc859a
enhance: add links
ankur-arch Sep 8, 2024
ac6a4c9
feat: more specific instructions
ankur-arch Sep 8, 2024
b9bc658
feat: add prisma queries
ankur-arch Sep 8, 2024
b53726b
feat: add more limitations
ankur-arch Sep 8, 2024
7291494
Update content/700-optimize/index.mdx
jharrell Sep 8, 2024
2c22fef
Update content/700-optimize/index.mdx
ankur-arch Sep 9, 2024
02c2c5b
Update content/700-optimize/400-recommendations/300-full-table-scans-…
ankur-arch Sep 9, 2024
968c444
Update content/700-optimize/400-recommendations/200-queries-on-uninde…
ankur-arch Sep 9, 2024
19d8cf5
Update content/700-optimize/200-getting-started.mdx
ankur-arch Sep 9, 2024
3fab0f5
Update content/700-optimize/200-getting-started.mdx
ankur-arch Sep 9, 2024
ebbf20b
Update content/700-optimize/200-getting-started.mdx
ankur-arch Sep 9, 2024
371585e
Update content/700-optimize/200-getting-started.mdx
ankur-arch Sep 9, 2024
78aa10f
Update content/700-optimize/400-recommendations/100-excessive-number-…
ankur-arch Sep 9, 2024
749bd21
fix: update performance page
ankur-arch Sep 9, 2024
a06949c
feat: add a limitation and an faq
ankur-arch Sep 9, 2024
ae39e16
Update content/700-optimize/index.mdx
jharrell Sep 9, 2024
321834a
Merge branch 'main' into optimize-docs
jharrell Sep 9, 2024
546b91c
feat: add callout #DA-1328
ankur-arch Sep 9, 2024
6b93aca
feat: make callout the main focus in getting started
ankur-arch Sep 9, 2024
5cb25c8
fix: add links
ankur-arch Sep 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
"Nikolas",
"Supavisor",
"inshellisense",
"janedoe"
"janedoe",
"unindexed"
],
"patterns": [
{
Expand Down
23 changes: 22 additions & 1 deletion content/100-getting-started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Bolt,
BorderBox,
BoxTitle,
Inspect,
Database,
Grid,
LinkCard,
Expand All @@ -33,11 +34,12 @@ Explore our products that make it easy to build and scale data-driven applicatio

[**<Database />Prisma ORM**](/orm/overview/introduction/what-is-prisma) is a next-generation Node.js and TypeScript ORM that unlocks a new level of developer experience when working with databases thanks to its intuitive data model, automated migrations, type-safety & auto-completion.

[**<Inspect />Prisma Optimize**](/optimize/) helps you analyze queries, generate insights, and provides recommendations to make your database queries faster.

[**<Bolt />Prisma Accelerate**](/accelerate) is a global database cache with scalable connection pooling to make your queries fast.

[**<SignalStream />Prisma Pulse**](/pulse) allows you to react to database changes with type-safe model streams in real-time.


</BorderBox>

</TopBlock>
Expand Down Expand Up @@ -195,3 +197,22 @@ Build real-time applications by subscribing to data changes in your database usi
link="https://github.com/prisma/prisma-examples?tab=readme-ov-file#prisma-pulse"
/>
</Grid>

## <Inspect color="#16A394" width="27" height="24" /> Prisma Optimize

Make your database queries faster by using the insights and recommendations generated by Prisma Optimize.

<Grid>
<LinkCard
icon="fa-solid fa-arrow-right"
title="Get started"
desc="Add Optimize to your app to gather useful insights and receive recommendations to improve query performance."
link="/optimize/getting-started"
/>
<LinkCard
icon="fa-brands fa-github"
title="Examples"
desc="Explore our ready-to-run examples using Prisma Optimize."
link="https://github.com/prisma/prisma-examples?tab=readme-ov-file#prisma-optimize"
/>
</Grid>
meletj marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ tocDepth: 3

This guide describes ways to optimize query performance, debug performance issues, and how to tackle common performance issues such as the [n+1 problem](#solving-the-n1-problem).

:::note

You can also use [Prisma Optimize](/optimize) to debug slow queries and follow the [recommendations](/optimize/recommendations) provided to improve query performance in your app.
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

:::

</TopBlock>

## Debugging performance issues
Expand Down
27 changes: 27 additions & 0 deletions content/500-platform/10-about.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,33 @@ In each workspace, you can:
- manage billing, i.e. select a [subscription plan](https://www.prisma.io/pricing?utm_source=docs&utm_medium=platform-docs), configure payment methods, or view the invoice history.
- view the usage of your enabled PDP products across all projects in that workspace.
- invite other users to collaborate in the workspace.
- access the [Optimize dashboard](https://console.prisma.io/optimize?utm_source=docs&utm_medium=optimize-docs) to measure query performance and receive AI-powered recommendations.

#### Optimize

You can access Optimize within your [Prisma Data Platform account](https://console.prisma.io/optimize) workspace.

##### Accessing the Optimize dashboard

To access the Optimize dashboard in your desired workspace:

1. Click the **Optimize** tab on the left navigation.
2. Click the **Launch Optimize** button.

##### Generating an Optimize API key

To obtain the Optimize API key:

1. Navigate to the workspace where you want to use Optimize.
2. Ensure that Optimize is launched. If it isn't, click the **Launch Optimize** button.
3. If it isn't launched, spot the text in the Optimize dashboard that says, "Start by creating your first API key __here__ and start using Optimize," and click the __here__ link.
4. Click your profile name in the top right corner of the navbar.
5. Select **Settings**.
6. Click **Create API key**.
7. Enter a name for the API key in the **Name** field, then click **Create**.
8. Copy the API key and store it securely. This will be used in your project's [`.env` file](/optimize/getting-started#23-add-the-optimize-api-key-to-your-env-file) via the `"OPTIMIZE_API_KEY"`. Finally, click the **"I've stored it securely"** button.

You now have your Optimize API key.

### Project

Expand Down
86 changes: 86 additions & 0 deletions content/700-optimize/200-getting-started.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: 'Getting Started'
metaTitle: 'Getting started with Prisma Optimize'
metaDescription: 'Learn how to quickly set up and start using Prisma Optimize.'
tocDepth: 3
toc: true
---

## Prerequisites

Before you begin with Prisma Optimize, ensure you have the following:

- A [Prisma Data Platform account](https://console.prisma.io).
- A project using [Prisma Client](/orm/prisma-client) version `5.0.0` or higher (we recommend using the latest version).
- A PostgreSQL, MySQL/MariaDB, PlanetScale, CockroachDB, MS SQL Server, or MongoDB database.
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

## 1. Launch Optimize

1. Log in to your [Prisma Data Platform account](https://console.prisma.io/optimize?utm_source=docs&utm_medium=optimize-page).
2. Access and launch the Optimize dashboard by following the instructions [here](/platform/about#accessing-the-optimize-dashboard).
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

## 2. Add Optimize to your application

### 2.1. Update Your `schema.prisma` file

In the `generator` block of your Prisma schema, add the `tracing` preview feature:

```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["tracing"]
}
```

Then, generate the Prisma Client:

```bash
npx prisma generate
```

### 2.2. Install the Optimize Prisma Client extension

Install the latest versions of Prisma Client and the Optimize extension:

```bash
npm install @prisma/client@latest @prisma/extension-optimize
```

### 2.3. Add the Optimize API Key to your `.env` file

Generate an Optimize API key by following the instructions [here](/platform/about#generating-an-optimize-api-key) and add it to your `.env` file:
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

```bash
OPTIMIZE_API_KEY="YOUR_OPTIMIZE_API_KEY"
```

### 2.4. Extend your Prisma Client instance with the Optimize extension
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

Extend your existing Prisma Client instance with the Optimize extension:

```ts
import { PrismaClient } from "@prisma/client";
import { withOptimize } from "@prisma/extension-optimize";

const prisma = new PrismaClient().$extends(
withOptimize({ token: process.env.OPTIMIZE_API_KEY }),
);
```

### 2.5. Use Prisma Optimize to generate insights

Follow these steps to start generating query insights with Prisma Optimize:

1. In the Optimize dashboard, click the **Start recording** button, then run your app and execute some Prisma queries while recording is active.
2. After your app runs and generates insights based on the executed Prisma queries, click the **Stop recording** button.
3. Explore [individual query details](/optimize/recordings#data-captured-in-a-recording-session) by clicking on them, and check the **Recommendations** tab for any suggested improvements to enhance query performance.

:::info
Use [Prisma AI](/optimize/prisma-ai) to understand recommendations and apply them within your Prisma model context.
:::

For a hands-on learning experience, try out the [step-by-step example](https://github.com/prisma/prisma-examples/tree/latest/optimize/starter).

## Need help?

If you need assistance, reach out in the `#help-and-questions` channel on our [Discord](https://pris.ly/discord), or connect with our community to see how others are using Optimize.
47 changes: 47 additions & 0 deletions content/700-optimize/300-recordings.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: 'Recordings'
metaTitle: 'Optimize: Recordings'
metaDescription: "Learn about using Optimize's recording feature."
tocDepth: 3
toc: true
---

The recordings feature helps developers debug and isolate sets of queries into distinct sessions, known as recordings. This targeted approach enables precise performance analysis and optimization by preventing the mixing of queries from different applications or test rounds, leading to clearer insights and more effective debugging.

## Managing a recording session

You can manually start and stop recording sessions via the [Optimize dashboard](https://console.prisma.io/optimize) by clicking the **Start Recording** and **Stop Recording** buttons.

:::warning
A recording will automatically stop if the 10k query limit is reached or if the Prisma schema of the app is changed.
:::

## Identifying a recording session

You can rename and tag your recording sessions for easy identification and context. Click on the default name of the session and type the desired name.

## Data captured in a recording session

Each recording session captures detailed insights about the queries executed in your app, including:

- All queries executed during the session.
- The raw query generated and sent to the database by Prisma ORM as **Raw Query**.
- The number of times a query pattern was executed, listed as **Count**.
- [Query performance metrics](/optimize/performance-metrics).
- Errors encountered during query execution.

Each recording can include up to 10k queries. There are no limits on storage retention.

## Recommendations from a recording session

When a recording session ends, Optimize generates recommendations such as:

- [Excessive number of rows returned](/optimize/recommendations/excessive-number-of-rows-returned)
- [Full table scans caused by LIKE operations](/optimize/recommendations/full-table-scans-caused-by-like-operations)
- [Queries on unindexed columns](/optimize/recommendations/queries-on-unindexed-columns)

:::info
Use [Prisma AI](/optimize/prisma-ai) to ask follow-up questions about a recommendation.
:::

Learn more about the recommendations generated by Optimize [here](/optimize/recommendations).
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: 'Excessive number of rows returned'
metaTitle: 'Optimize Recommendations: Excessive number of rows returned'
metaDescription: "Learn about the recommendation provided by Optimize for excessive number of rows returned."
tocDepth: 3
toc: true
---

ankur-arch marked this conversation as resolved.
Show resolved Hide resolved
Optimize provides recommendations to help you identify and resolve performance issues caused by excessive number of rows returned from a query.

The following query targeting a `User` model does not provide a [`take` option](/orm/reference/prisma-client-reference#findmany):

```ts
await prisma.user.findMany({ where: { email: "[email protected]" }})
```

## What is the problem?

When a query is executed without specifying a limit, it will return all relevant rows, which can lead to several issues:

### User experience

- **Viewing data:** Users typically need only a portion of the data at any given time, not all of it at once.
- **Impact on the user's device:** Displaying all the data at once can strain the user's device resources. For example, loading thousands of rows in a web application can slow down or freeze the browser, consuming significant memory and CPU resources.
- **Waiting time:** Retrieving a large number of rows can significantly increase the time it takes to get the data from the database to the user's device.

### Resource Utilization

- **Unnecessary data load:** Processing more data than required wastes valuable resources.
- **Memory usage:** Excessive memory consumption can lead to inefficiency and, in severe cases, cause the system to run out of memory, disrupting the service.

## Recommendation

To avoid these issues, we recommend using the [`take` option](/orm/reference/prisma-client-reference#findmany) to limit the number of entries returned by your queries:

```typescript
const users = await prisma.user.findMany({
take: 10, // Limits the number of results to 10
// other query parameters
})
```
:::note

Before applying this recommendation, it is important to verify that your application does not rely on retrieving all results from the query. If your application requires all results, you may need to implement *pagination*. For more details, see the Prisma [Pagination Documentation](/orm/prisma-client/queries/pagination).

:::
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
title: 'Queries on unindexed columns'
metaTitle: 'Optimize Recommendations: Queries on unindexed columns'
metaDescription: "Learn about the recommendation provided by Optimize for queries on unindexed columns."
tocDepth: 3
toc: true
---
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

Optimize provides recommendations to help you identify and resolve performance issues caused by missing database indexes.

The following queries targeting the `User` model use a [`where` property](/orm/prisma-client/queries/filtering-and-sorting) to filter on columns that do not have indexes:

```ts
await prisma.user.findFirst({
where: {
name: "Marc"
}
})

await prisma.user.findFirst({
where: {
name: "Jon"
}
})

await prisma.user.count({
where: {
name: "Nikolas"
}
})
```

## What is the problem?

An index allows the database to retrieve data more quickly, similar to how an index in a book helps you locate information without reading every page.

When using Prisma with a `where` property, if no indexes are defined for the relevant columns, the database may need to scan every row in the table (a *“full table scan”*) to find matches. This can be undesirable for several reasons:

### User experience

For large datasets, if the database must scan the entire table to find matching rows, users will experience longer waiting times.

### Resource utilization

- **High CPU usage:** Scanning large tables can significantly increase CPU usage, degrading overall system performance.
- **Memory consumption:** More memory is required to process and store data during a full table scan.
- **Disk I/O:** Full table scans increase disk input/output operations, potentially slowing down other database activities.

:::warning

While these issues might not appear in development due to smaller datasets, they can become *significant* problems in production, where datasets are typically much larger.

:::

## Recommendation
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

To avoid these issues, we recommend creating an index on columns that are frequently used in filters.

For example, consider a `User` model with a `name` field that is often used in filters. You can add an index to this column as follows:

```prisma file=schema.prisma
model User {
id Int @id @default(autoincrement())
name String
// other fields
@@index([name])
}
```

The best way to define indexes for your schema depends on factors such as the column type and the database you are using. Learn more about indexes in Prisma: [Indexes Documentation](/orm/prisma-schema/data-model/indexes).

:::note

This is a general suggestion based on unindexed columns we can detect. However, adding indexes can incur storage and write performance costs.

:::
ankur-arch marked this conversation as resolved.
Show resolved Hide resolved

## More on database indexes

### How indexes work

Indexes create a data structure that stores the indexed column's values along with pointers to the corresponding rows in the table. When you query the database using an indexed column, the database can use this index to quickly locate the relevant rows instead of scanning the entire table.

### The trade-offs of indexing

- **Space vs. time:** Indexing requires additional storage space to save index data, but it significantly speeds up data retrieval.
- **Update overhead:** Every time data is added to, updated in, or removed from your table, there is an overhead to keep the indexes up to date, which can slow down write operations.

### When to use indexes

- **Large datasets:** Indexes are particularly beneficial for tables with a large number of rows.
- **Frequent queries with filtering or sorting:** Use indexes on columns that are frequently used for [filtering or sorting](/orm/prisma-client/queries/filtering-and-sorting#filtering).
- **Looking up related data:** Use indexes on foreign key columns to speed up the retrieval of related records, such as when using [`include`](/orm/prisma-client/queries/relation-queries#include-a-relation).

### When not to use indexes

- **Small tables:** For tables with very few rows, the overhead of maintaining indexes might not be worth the performance gain.
- **Write-heavy tables:** Indexes can slow down write operations (`create`, `update`, `delete`) because the index needs to be updated as well. Avoid excessive indexing on models with frequent write operations.
- **Infrequently accessed tables:** If a table is rarely accessed, the benefits of indexing may not justify the overhead.
- **Columns with large data:** Indexing columns with large data can lead to higher storage requirements and might not provide significant performance improvements.
- **Rarely filtered columns:** If a table is often accessed but rarely filtered by a specific column, creating an index on that column may not be beneficial.

:::warning

Even if you index a column, the database may not always use it. Many database management systems, such as PostgreSQL and MySQL, have a *query optimizer* that evaluates multiple execution plans and selects the one it estimates to be most efficient. In some cases, this may involve ignoring an existing index in favor of a different execution plan that it determines will perform better for that specific query.

:::
Loading
Loading