From d5806f0da57b0a353edfb8d2f88b892e1fbb1621 Mon Sep 17 00:00:00 2001 From: Ankur Datta <64993082+ankur-arch@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:11:35 +0600 Subject: [PATCH] feat: add repeated query (#6815) * feat: add repeated query * feat: add example 4 * fix: change the title * test: check url * feat: cleanup * Update optimize/optimize-select-returning-all/README.md * cleanup: perform cleanup * enhance: add more context * fix: make the line more clear --- optimize/optimize-excessive-rows/README.md | 6 + .../optimize-excessive-rows/prisma/seed.ts | 2 +- optimize/optimize-full-table-scan/README.md | 6 + .../optimize-full-table-scan/prisma/seed.ts | 2 +- optimize/optimize-repeated-query/.env.example | 2 + optimize/optimize-repeated-query/.gitignore | 5 + optimize/optimize-repeated-query/README.md | 188 ++++++++++++++++++ .../optimize-repeated-query/environment.d.ts | 10 + .../images/edit-recording-name-chip.png | Bin 0 -> 17291 bytes optimize/optimize-repeated-query/package.json | 21 ++ .../prisma/schema.prisma | 26 +++ .../optimize-repeated-query/prisma/seed.ts | 45 +++++ optimize/optimize-repeated-query/script.ts | 57 ++++++ .../optimize-repeated-query/tsconfig.json | 9 + optimize/optimize-repeated-query/utils/db.ts | 10 + .../optimize-repeated-query/utils/index.ts | 1 + .../.env.example | 2 + .../optimize-select-returning-all/.gitignore | 5 + .../optimize-select-returning-all/README.md | 134 +++++++++++++ .../environment.d.ts | 10 + .../images/edit-recording-name-chip.png | Bin 0 -> 17291 bytes .../package.json | 21 ++ .../prisma/schema.prisma | 27 +++ .../prisma/seed.ts | 45 +++++ .../optimize-select-returning-all/script.ts | 42 ++++ .../tsconfig.json | 9 + .../optimize-select-returning-all/utils/db.ts | 8 + .../utils/index.ts | 1 + optimize/optimize-unindexed-column/README.md | 6 + .../optimize-unindexed-column/prisma/seed.ts | 2 +- 30 files changed, 699 insertions(+), 3 deletions(-) create mode 100644 optimize/optimize-repeated-query/.env.example create mode 100644 optimize/optimize-repeated-query/.gitignore create mode 100644 optimize/optimize-repeated-query/README.md create mode 100644 optimize/optimize-repeated-query/environment.d.ts create mode 100644 optimize/optimize-repeated-query/images/edit-recording-name-chip.png create mode 100644 optimize/optimize-repeated-query/package.json create mode 100644 optimize/optimize-repeated-query/prisma/schema.prisma create mode 100644 optimize/optimize-repeated-query/prisma/seed.ts create mode 100644 optimize/optimize-repeated-query/script.ts create mode 100644 optimize/optimize-repeated-query/tsconfig.json create mode 100644 optimize/optimize-repeated-query/utils/db.ts create mode 100644 optimize/optimize-repeated-query/utils/index.ts create mode 100644 optimize/optimize-select-returning-all/.env.example create mode 100644 optimize/optimize-select-returning-all/.gitignore create mode 100644 optimize/optimize-select-returning-all/README.md create mode 100644 optimize/optimize-select-returning-all/environment.d.ts create mode 100644 optimize/optimize-select-returning-all/images/edit-recording-name-chip.png create mode 100644 optimize/optimize-select-returning-all/package.json create mode 100644 optimize/optimize-select-returning-all/prisma/schema.prisma create mode 100644 optimize/optimize-select-returning-all/prisma/seed.ts create mode 100644 optimize/optimize-select-returning-all/script.ts create mode 100644 optimize/optimize-select-returning-all/tsconfig.json create mode 100644 optimize/optimize-select-returning-all/utils/db.ts create mode 100644 optimize/optimize-select-returning-all/utils/index.ts diff --git a/optimize/optimize-excessive-rows/README.md b/optimize/optimize-excessive-rows/README.md index 17ce9ab3f5b5..7b1a6575ab6b 100644 --- a/optimize/optimize-excessive-rows/README.md +++ b/optimize/optimize-excessive-rows/README.md @@ -49,6 +49,12 @@ Perform a database migration to prepare the project: npx prisma migrate dev --name init ``` +If the database isn't seeded, run the following command to seed it: + +```bash +npx prisma db seed +``` + ### 4. Open the Optimize dashboard You can create [recordings](https://pris.ly/optimize-recordings) and view detailed insights into your queries, along with optimization [recommendations](https://pris.ly/optimize-recommendations), in the Optimize dashboard. To access the dashboard: diff --git a/optimize/optimize-excessive-rows/prisma/seed.ts b/optimize/optimize-excessive-rows/prisma/seed.ts index b42daf6cbea0..08fa011b8c7a 100644 --- a/optimize/optimize-excessive-rows/prisma/seed.ts +++ b/optimize/optimize-excessive-rows/prisma/seed.ts @@ -2,7 +2,7 @@ import { PrismaClient } from '@prisma/client' import { faker } from '@faker-js/faker' const prisma = new PrismaClient() -const TOTAL = 5000 +const TOTAL = 30 const main = async () => { await prisma.post.deleteMany({}) diff --git a/optimize/optimize-full-table-scan/README.md b/optimize/optimize-full-table-scan/README.md index ea8d81a36389..857a17e6331c 100644 --- a/optimize/optimize-full-table-scan/README.md +++ b/optimize/optimize-full-table-scan/README.md @@ -49,6 +49,12 @@ Perform a database migration to prepare the project: npx prisma migrate dev --name init ``` +If the database isn't seeded, run the following command to seed it: + +```bash +npx prisma db seed +``` + ### 4. Open the Optimize dashboard You can create [recordings](https://pris.ly/optimize-recordings) and view detailed insights into your queries, along with optimization [recommendations](https://pris.ly/optimize-recommendations), in the Optimize dashboard. To access the dashboard: diff --git a/optimize/optimize-full-table-scan/prisma/seed.ts b/optimize/optimize-full-table-scan/prisma/seed.ts index cfe08136c408..291158df34d9 100644 --- a/optimize/optimize-full-table-scan/prisma/seed.ts +++ b/optimize/optimize-full-table-scan/prisma/seed.ts @@ -2,7 +2,7 @@ import { PrismaClient } from '@prisma/client' import { faker } from '@faker-js/faker' const prisma = new PrismaClient() -const TOTAL = 5000 +const TOTAL = 20 const main = async () => { await prisma.post.deleteMany({}) diff --git a/optimize/optimize-repeated-query/.env.example b/optimize/optimize-repeated-query/.env.example new file mode 100644 index 000000000000..90cfec3bf6c7 --- /dev/null +++ b/optimize/optimize-repeated-query/.env.example @@ -0,0 +1,2 @@ +DATABASE_URL="" +OPTIMIZE_API_KEY="" diff --git a/optimize/optimize-repeated-query/.gitignore b/optimize/optimize-repeated-query/.gitignore new file mode 100644 index 000000000000..2484fd1582e2 --- /dev/null +++ b/optimize/optimize-repeated-query/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +*.env +package-lock.json +prisma/migrations diff --git a/optimize/optimize-repeated-query/README.md b/optimize/optimize-repeated-query/README.md new file mode 100644 index 000000000000..2c28e258f0e7 --- /dev/null +++ b/optimize/optimize-repeated-query/README.md @@ -0,0 +1,188 @@ +# Prisma Optimize Example: Applying the "Repeated query" Recommendation + +This repository demonstrates how to use [Prisma Optimize](https://pris.ly/optimize) to improve query performance using the "Repeated query" recommendation. + +## Prerequisites + +To successfully run the project, you will need the following: + +1. A **database connection string** supported by Prisma Optimize and Prisma Accelerate. +2. An Optimize API key, which you can obtain from your [Prisma Data Platform](https://pris.ly/pdp) account. +3. An Accelerate API key, which you can obtain from your [Prisma Data Platform](https://pris.ly/pdp) account. + +## Getting started + +### 1. Clone the repository + +Clone the repository, navigate into it, and install the dependencies: + +```bash +git clone git@github.com:prisma/prisma-examples.git --depth=1 +cd prisma-examples/optimize/optimize-repeated-query +npm install +``` + +### 2. Configure environment variables + +Create a `.env` file in the root of the project directory: + +```bash +cp .env.example .env +``` + +Next, open the `.env` file and update the `DATABASE_URL` with your database connection string and the `OPTIMIZE_API_KEY` with your Optimize API key: + +```env +# .env +DATABASE_URL="__YOUR_DATABASE_CONNECTION_STRING__" +# Replace __YOUR_DATABASE_CONNECTION_STRING__ with your actual connection string. +OPTIMIZE_API_KEY="your_secure_optimize_api_key" +``` + +- `DATABASE_URL`: The connection string to your database. +- `OPTIMIZE_API_KEY`: Reference the [Environment API Keys](https://www.prisma.io/docs/platform/about#environment) section in our documentation to learn how to obtain an API key for your project using Optimize. + +### 3. Set up the project + +Perform a database migration to prepare the project: + +```bash +npx prisma migrate dev --name init +``` + +If the database isn't seeded, run the following command to seed it: + +```bash +npx prisma db seed +``` + +### 4. Open the Optimize dashboard + +You can create [recordings](https://pris.ly/optimize-recordings) and view detailed insights into your queries, along with optimization [recommendations](https://pris.ly/optimize-recommendations), in the Optimize dashboard. To access the dashboard: + +1. Log in to your [Prisma Data Platform](https://console.prisma.io/optimize) account. If you haven't already, complete the onboarding process for Optimize by clicking the **Get Started** button. +2. If Optimize hasn't been launched yet, click the **Launch Optimize** button. +3. If you want to use a different workspace, navigate to your desired [Workspace](https://www.prisma.io/docs/platform/about#workspace), click the **Optimize** tab on the left sidebar to open the Optimize dashboard. Then, if Optimize is not yet launched, click the **Launch Optimize** button. + +### 5. Run the script + +Let's run the [script with unoptimized Prisma queries](./script.ts): + +1. In the Optimize dashboard, click the **Start new recording** button. +2. In the project terminal, run the project with: + + ```bash + npm run dev + ``` + +3. After the script completes, you'll see a log saying "Done." Then, in the Optimize dashboard, click the **Stop recording** button. +4. Observe the queries with high latencies highlighted in red, and review the recommendations in the **Recommendations** tab. You should see the recommendation **Repeated query** and click on it. + > For more insights on this recommendation, click the **Ask AI** button and interact with the [AI Explainer](https://pris.ly/optimize-ai-chatbot) chatbot. +5. To create a reference for comparison with other recordings, rename the recording labelled "Recording 1" to _Unoptimized queries_ by clicking the green recording label chip in the top left corner and typing "Unoptimized queries". + + ![Rename recording](./images/edit-recording-name-chip.png) + +### Add Prisma Accelerate to the project + +To apply the recommendation, you need to add Prisma Accelerate to the project. To do that: + +1. Use your database connection string and enable Prisma Accelerate in your [Prisma Data Platform account](https://pris.ly/pdp). +2. Install the required dependencies: + ```bash + npm install @prisma/client@latest @prisma/extension-accelerate + ``` +3. Update [the database connection string to use the Accelerate connection string](https://www.prisma.io/docs/accelerate/getting-started#21-update-your-database-connection-string). +4. Regenerate `PrismaClient`: + ```bash + npx prisma generate --no-engine + ``` +5. Extend `PrismaClient` by using the Accelerate client extension in [utils/db.ts](./utils/db.ts) folder: + ```diff + import { PrismaClient } from '@prisma/client' + + import { withAccelerate } from '@prisma/extension-accelerate' + import { withOptimize } from '@prisma/extension-optimize' + + export const prisma = new PrismaClient().$extends( + withOptimize({ + apiKey: process.env.OPTIMIZE_API_KEY!, + }), + ) + + .$extends(withAccelerate()); + ``` + +Afterward, continue with the next steps to complete the recommendation. + +### Optimize example: Applying the "Repeated query" recommendation + +Next, let’s follow the recommendation provided by Optimize to improve the performance of the queries: + +1. To enhance the performance of [**Query 1**](./script.ts) through [**Query 5**](./script.ts) by addressing the "Repeated query" recommendation, add a [cache strategy](https://prisma.io/docs/accelerate/caching) to the queries: + + ```diff + // Query 1 + await prisma.user.findFirst({ + select: { + name: true, + }, + + cacheStrategy: { + + ttl: 120 + + } + }) + + // Query 2 + await prisma.user.findFirst({ + select: { + name: true, + }, + + cacheStrategy: { + + ttl: 120 + + } + }) + + // Query 3 + await prisma.user.findFirst({ + select: { + name: true, + }, + + cacheStrategy: { + + ttl: 120 + + } + }) + + // Query 4 + await prisma.user.findFirst({ + select: { + name: true, + }, + + cacheStrategy: { + + ttl: 120 + + } + }) + + // Query 5 + await prisma.user.findFirst({ + select: { + name: true, + }, + + cacheStrategy: { + + ttl: 120 + + } + }) + ``` +2. Click the **Start new recording** button to begin a new recording and check for any performance improvements. +3. In the project terminal, run the project with: + ```bash + npm run dev + ``` +4. After the script completes, click the **Stop recording** button. +5. Rename the recording labelled "Recording 1" to _Optimized queries_ by clicking the recording chip in the top left corner and typing "Optimized queries." + +You can now compare performance improvements by navigating to the "Optimized queries" and "Unoptimized queries" recording tabs and observing the query latency differences. + +--- + +## Next steps + +- Check out the [Optimize docs](https://pris.ly/d/optimize). +- Share your feedback on the [Prisma Discord](https://pris.ly/discord/). +- Create issues and ask questions on [GitHub](https://github.com/prisma/prisma/). diff --git a/optimize/optimize-repeated-query/environment.d.ts b/optimize/optimize-repeated-query/environment.d.ts new file mode 100644 index 000000000000..4dbd16ff6472 --- /dev/null +++ b/optimize/optimize-repeated-query/environment.d.ts @@ -0,0 +1,10 @@ +declare global { + namespace NodeJS { + interface ProcessEnv { + DATABASE_URL: string + OPTIMIZE_API_KEY: string | undefined + } + } +} + +export {} diff --git a/optimize/optimize-repeated-query/images/edit-recording-name-chip.png b/optimize/optimize-repeated-query/images/edit-recording-name-chip.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4d482cfb4c21248e9429241d648139bbe47ca6 GIT binary patch literal 17291 zcmeIahg*|Nw?0fWh>8WaA|k~?m7?@sL`1rR^d>?=2}zLNyPcx+UPM3)1V|vE7Yi*E z0ZD|=loEQ779bG5c+UHty?@{Fm4D!HT}g&aduGj=HEZ4LhUa$;wONl{I7UZD$EtJZ zmN6Y2GmKXDKMJ6|4~f;b(9zM`xN2(N)zQ@CyXy%9xw-@C=!9N7K6vosj;K(FgTsRd z9X;2Ck9qnTKYJEq{2;8grI+thOFLh0OGcWF&E)yhlZ^L2&=uTk#eh%5@a-bSJ4(-D z77hZQV{@}cllJFJd`LR_n?m8&_^ahP?;OxSjGB&o!v+A{=H^q%Yj{id2|Hh+4H?X(ihhjDr{cDCsgPPz2RBMDM$CgDp;>S#l@1b;;~CAng0&IQ1$#Q@{= zn^79Gbd@KfBs2x07^2QZDZJWn^l~c~uUmNx|E^_**|J2=4}0>%9y9>2QKDf=tZiV&c;1D`*{9qOg%uX6dnS}4-WzrL2Z%=ceSyum7$ zEe!7RX~H~#e6r%##jjshJ;uk!r|jtjQZ&AG`(NE@zo}ey@%Hvml#uZA^Aq=z5{G#@ zOWaUUP>{GTDIqB-Mr$GF6#(^i@E3!6UHR`p{yokupqHbktB1EM49fRwT!)7+A8(b* zmw!$4KR^HdoIroqzh{Da{cBmY1xoy?k+>m#UE+Vnrgc^R^{wJvSAU?pp!ag|6NVJfS#H#2yISp)xWpqU!DJ1`LB-3 z62F%I4^jNLod4@vnxIvWDNFp%rl}rN3>}uIqf;x?xutR6pMH6a+5az7e9O;7-J3`G z^PhaFe>U(J*Rf}p8AN1neMaP2s2@3dH{i@!Caq87L0Xm9j$R&s^IdKv8y?lU6Gp0a zNa+EwCxlnj?~%ySW7)M{#9o-d&UibDIGX1^82yBf;V57DAKyG~9*H!X8&*&_v}Jhs zSw4Sk)Srj@Rl6Nd*J{mM!=g`5&vaUy?oV&D0j2(Lz~4yV|77@oYV-d{;3z9oq)Ixo zlOO2KRVRKuU9;2=lPCOfO6qpSw<)iiy^()3AmJ@KmnTzO37<;; zvdlqiu}LNxCJ?-XC8X|16V3FuJgJZNB`@6@;8Qky6Llq?G%e3{h^3(yne=NVEOSzv zbQYd4e0V`0SWNwheUZS%md!1^dm-8O=1u-jIbxcU{K7(}30F}r`jyGYMoL!q_Jmj%IpIObEEKAYN$wVf^5PpmTCEAlZ#f6jK#>|25S>3#gbWdgK zH!pSttZ=^G6v|%;Uw!dsxvJk_ihTK~n?>OkzNRPa2##HnzgeXO;68OK-Qnj*bOIER_9RD2RQBi*PLnCo(g zw(#9mrf)tv4(CtIX$r^gIi#D~L)KyjOzyG46Hi-qrTUxkcRr4$)t2KqhZ`~d92fxhbjctC2F;#J?Q_XO`7|^%5KT&cO9{zXGo4#b z(b6vWjo#>L4Tpfu%TpoN=wb3}{wsx`vM64KY)CI8Kd1T zODs`E_@CaQ+)~1G9v-$Nj#le(8~0m(yn)s8)Fbw;1RUY<-SZW2;y&3h>xbI}%XM%$ zj=!$i7V*43leaY7XpUGJH&ygo7P1dk#)Ts8RyHhpu#UT_lZRWc0H<~hjPs3;4A+Jf zSIMK&M+Y&*(a}uU4PmL7GV^g%gf+JbV-4fejZ`<8A3$8yuq3tkxp9G+Pk$bKC2aaR zGynL~V1P@7DS;Y&s{|I=bc(gcUN=d|fjBU|(KfKtr3YzN+;qdzNfqV5cABqEkKxs- zTCG_}o5*e2YedqZz6ZvpcdzFnv&!bPBw_0jA8s$_o>V_ON=wc`To6>@;i{PwY#n?` z?W>Wj`?ssDtr|#Apdp{~jT`r7du{oK;O*EBqPD-vSFi35qY~wem1q8}SrLggEyO5{ zu$EBz-nWBY9dB>poxP9c)9tXZ*Lo792Qbo+<=(^g^_hEBaxO3qsV1RgHx7bYV?q z*3{?ChAGy8TNM;&E&QppT0x2XNQLDSRaKj&-D$4cpXe3eT#6dp07sITh{tGv$je@! zUQ`5ud6%355;IC|4BF~+49R_EA9`K_zgg2Z#1pQ72Nz6uLaxmj-1nun5)8AI zI&oswGrL@#ed~ips)-_xOxL(^aRKs{mM=V;*SM3o4>1o}(G04*4F-L^LTixz@b^K3 ze9J!`>n#<%Gv+V!9kW7iimnpF8gyi;VM{@Unx8KL(}A7O)hO^=()M9 z6A$}TS8`R_MSJ%>dE?24t*rFd%EY>2Ye`$owqxb>^A}7QCnhP@* z8!242Q)YcLW!0`>P0>%E64<(y#i3IRNHCEH^#saEu|#=kp9tx1!u$A9R0DJ2xpwxT zB63S5+~mf%sD0B1o*^W#cLekKe5B?fuC{vKGX{nJp36Mm%Jol=oKgaw;wrr*u{*5ilvkY!@`}ULIgH0nOXvnGrinObSj5YLBhkdMz z-3m#5|5Wej!~}__zRWXO_f3Q;%pj_ql}m0FjfK|l^m0wB|Dex|SoD5xTKuHcw$aer z&~$2Qx?hkN37%M}tNjcaP7vcvP`XlE<5DjyEoUT87T?v5*fG>`yN>9>fTEh3U&;f(zcAWd0 z*M^zxyO!p?3d=exddgkXX9=Vxt&>F;y?y#0kp-`g#MrR@KwJkV$qbrfMR^VMj_IoW z_|AIaYbsZF9cH(H6#rGZU9@Xoap2q1q03_v3btBgF&1XGF{Zgv$9#Nk@iKM#!nH`k zjO^*4d||DNY;2cNMLm^jy?n5+wf9*QE6O^Cy02N(jFKMNhr*<+Dar%ZBJHN=v0asM z^YO5$EA_n)+Qn6+NIWtB$l9-7LP)414$kY{Xw_3Xq`n+}X@7}Yu13K%xjhHjrlN;x zoxk-da;V^3dntpNa<9=GwtR_UnGgL;;b$aHom#qLAF>;Jf_E*lN1*9F<*a9pwQQx- z?R$2KS4|&YE#5;BA9Z$iB3%bTmUZ6g@KNs+%RX~VvUsA&hvD_}`=yR`a*g(f`z&?p zuR3q`i0?YIlb+Gs-s$ovFm;gK4F?CfG*)kHcyqn;!S!w8h|QxZDH#Ia`9H*W3cq<9 z{k7-4==TIUP;PQEf1;pKO7b-?9KhGmqTJ5bm4J@Dmbd7R$4i?$3ou~h!Kvgu^rTdc3nE2sEsw?^My=K>zM z&L{=zs48*_3YJk;aqO9%2`31o5wHyaO0P57hA{@vURYCGR4 zx_YEgH$gZt>wMBf`?04(F@!cI=$MXw{2{(~<&iycf4F%@TJmM=Ao|Wtka49%7Gu1j zI=*JexU;|YwYJ=8?ZZ?i{Ol@rvdoJlOY^;BIqR<~TpJqxv=}COSF$Gh{&6vhpAMA= zKhw`2wzG+PE#*;|-m;Oz0City0o|Ks$hT?g&_G`RFqu26z<&tY;h>Sv=E{KnNA&mN zjKW`k));!GHTI*=CLy65?Y@V_5b7=VOp*J*H{I-qjd}X06MZBmBG|81_OL-$xo9mz zz2Ip=hp7@1lCG7Y-c)aMSnPOoJC=q$HP@QzAG&x3%kW7E--IoK^{^%F-435Dn-~=l zI3!@BV~7w{UzL4D62~8UzCy34ui{|Pv+P=bzVGNF)X(wxb9MNof;A6mN#A^i&wo)4 z^WypC!%P|9@zV{g)AiWuONX=!pE!EDVKdYE^R2@oYQ9%Tj*bJ?#%4wi^Fvx-Oh?Ce zd&(ZZIqZ<1?qJA|2!3?PuD6571>ar7@uK2iBw3rTT_ zFMnio#rhD=IYv)~-Jt;8U03*%mbZ|Zj*jk*t2o>~a(s@1b)$B3^Y$tZPddH+$IT4BqpruF z_-Ij6E}DjCsOMUTgof0fY1o{p|2XGHCFk%77%-G+ykt2O6Sk6|1BylrvKEereB zFMJ?XkG-t^ZUIc0O)#V z0w8G9f;;L-OQ%4KNf>hM5rX4SwqpC#5$Q}bDX3n$apz}9U}@ZUr`dCU7vnTrCYXdW zmtcM|JAXWxs-mw@ZDnNR&QwzvKk>fX)ge983iFEZEr#ipAtk}h4!$|p22PAdrOziM zyv}gWg?^FomWTn1h+X@dc*_J7u&~818HN`r4;l7a~KBc}IiowLt*gn!>QorIG^iM21pdj3lbkMB0;KNxl(B0ix{lK*R}uvL4E!` zP{ro8l7aerf&pGT<&v)0%f;4}cJVV7pEJU9dB47Mm#M8Ce{5WEUn?kn#9YO8g9j&J zG6eA6-&>2D-w@6W)>q&>@h9oa2ORkj_0j!yX>mBFr7Vb-b<&NuuV}b>cWOAt1vdtO zhRJCR!v$2XM9qc?J)ajIKnAO1_LuB0rXViM6kMBOIUf{fn%39uS^6PM;tRz_Eg;&P z5^_GmT0%~dG`Ld8o*AskCnjcVJUDQ*?tT(X|C!|<^&iS`=8^-O6B0I-nWDSZUE?!B zYQU?G;2Wcnac4o1n3AGkWYFM)_vm(xU{OxXbfmCr>XLGeec)G!GX`uqZoP=XkVr0H zH0p55+Tz>?Z})@aJKL76rrd=&t!^6Yn~~%eK^<_tFeIg|n%4;{4KooY`y^_kk{_7R9;Gh5rY+H=kihsom|h>!&$jZ*J;O`Je!6qu{4GHV2uYKi^L?IsS}c6{cJ2!eR@%K)zdEwm-$5&JXo0R(*(Uv z>lhlo?k^8}_41AG%!`2vJBVxl#(kFKN=?nAS^+k7-jh7~$@j{e1o5^*mTp7O)ZSmq zRCLUV37yj9yz%znUcAqJ_U{jVe~EPP=S7(H74g45PN*smS~ZJ5E~TN^R|GCbmw9Fc zj}+yygvKQfE2UyTjDeTpw_@MfeE|4q_Ee@1TdtADS$&VPX1QIL6uYLGBIuqFSma(F zikmFY!35uO&78Nc_XZB9G?>c@lF%9!tfzzGW>kwS@=kNzU%FpbXj?4TS~~T2P=>kH`lat@hMhupP`DenM>ZL#mb1JW3jIUIf5@U>(6=&Nmk0P!dr(<{_I&! zgTSRLTdkMN)fP`Jd8k!~kg}Q^Eg9vIb9NOF>c%^0*9A4-T^WIQ*&4TIJgseVo<`<_W0bLOr-fgV>=i4TIaaXQ8iwv2)t%iAD4q!<=vUak_t_+gTT3#CV}uwa{OcX z`i)Tbix)*rMNChJ#6A;x6r=52<0!UD$wfKMb(j|hyDPX3mp-RqRh_95)XVlEWH_tr z5Zq+lA~)e@+)ef7cQ+i?yj?>B9ZT+4Hl%%Kcj{NePQQGlhAm-T?EKPB(S5$US|HE( z^u2oE?I%7>@5TbOj@1}uNNR>=T-UPm-@U=%q_1yTVgk?Dk-YU5%mw@XEjIb-xQn{M zL0_Y(glX%(V+2WsvS885Gc`|lp`r|kRFsL@EJOv3&@D@{^M$y5C%&Qo#H-JTj%4}d zwzUv+Ei@665|1Gc@x4#6;(-K{3=Rh$!9= zBbQ+i^iv|r-NXMIC*~U+3UGh3Aw%K4s-FSZm6!UrO94?~%hzv-BSuC6uy)w4-i4&+ zsp0|@f32H_9&*-5{-Rq|x63YS2a08FJ&Z`wl0H1!*HOX93B&Fpxs~iZU77h53B4s*5o-bi2TU( z5X?#H8`;9p+xJ-bjx5~rI%#sulCU2uK|`c{Lf!2Qe|**EPqBiKxJ8du23x zR+iNKqm_4?U$6blyuvSe`9pQQT+^kz^!~Cw=zK=^Zfs_uU-Ko&m8TQ>Xcs}e@AyUg zi0FN0r?DqJwT2@#4z`@CHTDQd@Ne=SG}VYm)K+Ko9}_sm!7A%kGJS4laU^`a7_y7y z9=wfB&`d|?TuwBwoN_T4A(xy}`Q^~wj}Zdb&&d|M(tTC&Sag@@UVOr+1er9W7>*#n z0ASZrMV(Li=xVEtFL^Af>+ylr&86I$3D*aiRO`Qaeki*pgVtCrA*9?{?24UXOMDD3 zA8As&kNg(8y6xOUg~)oqGYR*h56L*mnRo4WX^9uvA4*17y8;j(z+&Ks3!_7x9V623 zf?JK^N65XQJ#4s^GFjFb@NLhtQugHPXJd?A#h<@cg-qPg@G5rYoTUo*+up_YAv~QF zxaRDDv-xCOLPFyrFw6>RORmYgvHys-)mp+2vbCp$Y)Pt%l}We#$gJjW=M`Gwb{{Sh zYjAE{<%|Oq>{Qwsm)5Sq!Y==OlsvPhcPf?3qBbzQVTZ~g=`_hGtGXZFRDpGlWZ^HTmkRi>Oa`CF5xX!LYl z{X|0HH6U^x)~NR=fv$q)Zz{_ z+1R%9D6+&m1f278YS|aF(WwoKkd-#043J)^VBy<4$JZ}<*CP|Jt$zz>%9)$6R^_G? zRF~M~H+akRnNQu`^ge1ni2NR=pL>N%|8zrTz$~JvGzy%%e!E$8eK1r0Mk}?Apx~OX(laSR6OW?g*FAE)oEth#oQEe0AOt_%L4o29 zEl6Kw^OfGv{p=E3R7TP@6RXf{=^^Ds7W9Mx-d6n5rKfOVm!Zdx)C{V~7J4}tmGb1Q zSzlPzPygRX`w^oIb-r+FZqQa4U?!^txH2A~=4wwaas;O5?qvYDIC=uwS8$V)rl4h< z5|_>85K!a%=BpddWJ!L%MPg|pxQiq{in`q^luK!bxamy(Kzp-q`&hZneka$7T^0Ja zGH@_UsuI(wU$$nAc0(_Tqo6RGPK(;FN%lC|?Q$chhwa4%AP{D$R|7Mgv5f)OikF)v>?erI{8UBCfy=mFDlthH7yg{R z#>ddKz$%M1c!3ypYLkF=EOybEspd&{$cQK*m>7HV7>f10w@h^$-|JxVHp@`&wzIxX z#*N2!tf&Mn3rj1R#HXVsVF7FDsZP5~N0314Uf%c3-6QpN5@ISudWmlT;aLsbgY~Dm z@u+k#v%#u))Jw9;TGG;R=K3-dal~IGkbcw7A+k85alV$XK90w{@QwcN3L{taP~WcK zZPNU4fd}RE4YI^+SL~MCUBA_e8?r8@sK5r+rI7V0nB*6xRVn>>%VIGZdI4K&d?SCF z#F4o)PELg|q0Qs;DE+*9sL<*S(hf1pA!p2VfLK{O+X) z?Drx3owKl(D8^hF`mP;Aj{XT^6Jze{WhLL?yfUh)s(WN&#xO~`(NAhtv|{lmPR5k3 z%DWCAwW%5_*{3hF&VMST$Xk^ZnuW4x{@_AVaC?66v$yI%ZYFOVy{p2pnTBM{f%$>p?9tVX_0{`)XGXwy`9q=`_Ek3xm#? z0X_B`@ye@nckvb@+F{Pp7NsFFLFQPeu&vEgYd^qG@yfUZUXO_@n*4)%Cw=N_V&7&+ zG;T=Yi|r%xevf6Tw=%5I%NG-4mi4kR+QFMRbG(8N?6rW4{34PFxjPs_X%^rz$qc&v zF4WilskxN53<|y67q5evc-ol?E^tp4BvG#*LU|4*-|N`w%4z{Ds}p0 zwaLu#S@v5}mNMV$+Dl1r{;X)cUG_U>nn-%1cvoxx_cPm)kB7yA{!kf`I(i!VSVxdLkOv1sGLnu`mLnZCLGA2 zZBW6@qvQokN622=(RvU9#OS7eI|_S2^ewj%J?mXpIy;om%K_=5#lu5}l&;cvN<2$W zlgccoISviNj|YenRafT*1zh$JF~K6md#$%n z2$!e6WrcXi*m7FNj8ZRCOk($DR_UT>Ult{GuX@`)aXz3xrk`)7o;OUa?^MXwv$wv+ zn6PfR(yjHY`VI3D*=gBwtRgy*va;Y1Z$jd*3+QvIGOV_zewo}$>}$H3Z6J%FihU^> zu7ZWE7M|cyz1_4wZE9Y$Xtq8R`&yHyviakP5o%cmwZ*;e?gA)5??2a(W&c*|S63$A zKEIEnn^}}N@jA^D=zX5+ZsQPBv5&!|p1urSaW>)o;~w--pKZ5~_wu9iZrOD71(%_4 z3;~$DA@yfao#dv?AfKbIF4)yTi6_=IXo|7(923D6(aBo&c8S$ z-Hd)XWEBJh(8xFYk&#>VxcfK15QA%2eCx|o;r3Yp2gwcyVqIzHhy5Ll@Y(~C_434w zuzT+ZZMaA%H5N&guX41X2M zPWEvgGD$2_X8a(`S%UnWv@^u_!-(Tl$~@s9*#gzHtZW4Yutc+*m zv+@jeSEPcO-c_>O*M7il7{V`q+3RgsL#)qRM`d!nt(@(ybkk_kb)E-$yo-u;+3;N9 zjNy?jB7IR1I!1>7wS*Ly;Fhwo#Eo4(9T+m!ZB;$eWUGd4Iyal!>|37lY2z;i%z&`u zS~p<^mRJ}JS;on#b2;MZLJ51_W7RjUOkMcwGZhSOfae!>>t}S6*aYt^EgifcbMy_P zyf-kouKWq{G;`u&TRK~3psgDhuc_T-eOH&_X|K@si>~!4KpfrbDGoJPtZWb>Hu&w- zzH3;8n!%QTk56-_%~vy#_iyngia;>?sp*aNkxpz|ZI~F^x_YSuaL25CjITIDvb(jl z^-X%W^k~3(weQLN{Bg&n$D9%f&m-2yyorc0fjM%NN;$~xq|{6v%V^z8-c0g^ zTZ3jIBE?_Br53)NDeqb)vwG~ifMa_X0!%C^(HQ*1sIw*b*+~E+$v;@#jgZ|(MpIe)Tk?YjTP95yDc=n0 zLg73U`|o>KY?tclGUglHe0nh-y^B-Ia1!?NWe$xavK0$VP@f>=?B8O+*S@@+uRQtwHxC1OLro#jgJ`h z74)S6pqmP#wcvPLYvs{k2d!q0yGcdqKTNwPl=dmJ(jmPv;iZLenFlMxzHHzPr( z1k>}j4NX$4tgo=&#VyT{LUUZ2WAX_bf9!wR3h zY)52xE_Tlfl%YQ^crMtTyr@v6P`+!2=fVY*3?n(xAC%`<_mvn(#aGX(LITHnv$Dd1{QoW5VZIk!OOZPY%pPesP9Fi1ZuY#ovT%Vp&0k4r;~ zy^8?S#|YBri|Dx^bpkAJ1)nA z(rt%l9@cj4%_){vISS@k4hK${AuOG-!-`jOgUq}X3LR`IKMN$9lJ`LnBl0<(6qH#B z3X*C=t}Ykeu@yJ!IMf~KaIuC7Zi zo51$F8UJT_)14q0roow(K~|_z`@pFy z)^@d&p=_-%!T&(Sq~*K;Kesa7jhx3!ipg6^A!~D^WQbV_=(}Qiq7|FD9)A#MRIz>D zg7ybCCNU7aur0F%qT_(MytSRhENaCJrWP1+5PMSYqQ=8`b9RKFks~Aqah~xhD z+BwTcP?EPH+n(YwKhw)jb=K1{fBBvde99er)@6v|Q!HG#B#%(37_);*HLWy*N6yzb z-!6F}dwykU(7b1Sh_`R+v9NX-?fS#;lX}?0n;{D?Yft|4UaK1P?0rc_Bo?0wg~ks` z_J#Rgfa1k_W$w}i({h|M0&ciu#PfHHy>@=4f(mIFZny`*H~`)46Y~=51{E3vVOGz` zM*`%DP(zvhtfH_xS=CUVOn|Sn5K6+KS!|+Y5f~^dxII-nMj*b4DW1_)@^QH$MHEd6 zOF_JPZUP$FykT;Z$2(bi)AuC$tgU*KuMFJ0dN_(BE2!qG4*{pZ&*|Mbf}fytpY7-& zoj7~#Q-*%met_>{-Mh07PciR#xBA%@e{Bq~F7PGigwQN&kgc=A)vLE2>WABB0(N;9 zLNZ7Dr!H69s|>|5Dx%;i zYj>(9BeDbpaqY1gdQgffBAZj@tZFiVB*Tpv>edx2^TYTO3jL=PW^|Inrgp=tPQOqqBvb?n5k&t z$2BwgAwEcGgq6{CZq0U)cdj0fe16~}>%I-N=5WV($2f-(Q7M;H&p}X@2V4HKJ$B-A z8S&HaXpU3ARyqbijMoa{ z71Iwv&5BiNoDU&Y3B)cEFd0DWW~dmYz!Eg*e8A5o2kS9C7*i<9!+(e=278A(A)(Ga zwnEFjYFGg8?nd44Nu{vw36W2n?Qa|zNmpO4;T7zN)Cve`mIe>IJ*iHCh`p1M9-i>( zNoAH!BTBOl^xgo*`s5B)=`TfU9VqfH!!hd%iX}Nfm~)S{Qxq~Izr^uilid8KwOX>U z07ADuEXaf8d@%^>>64*$uH^$!0t2H-r$Z?pC2Yz0_x4ASwD2$Ub7?D-s68ePzMn~j zf(4e`rxwSH`t0~}!xBwEZzARk4DerlV7rgch>;dU&JdFew#&qG^V2|M0F8fE#tV@crg zIu-K4=`>gB*5`K9bH$?}8jkXmEaa9VFDr;#O95Fw{@%yAo+aM!`&_3wJ%iN+xl3Zh zPVMK^zLc~toHtA#V=!z-B&tuMO9~7WW;cDuoNSFS?*77-72xEJEUIUVtqLv3ftCP3 zPt|rRl%-wLf)!SrcUEXL;;}319@Ag6ZCdHXp2GQW$~dlMWRemU1sq{mG&g$sJxEt^ zxeY8XWm&K1L__tTA^P5>KTOm=w?qS2XLjNB9gjKWRgROb(tbX~CMQdD%e+lT=Ifc4 zRz}qRe5(5PEdJ>`)6`ql-GRU+Mw&#N!^`dOn z;*guNX82x?PFP|w)=Q$1KZEr>C(^N*Vk(3Ztol_>2F6^yM!wc96x=pqf4zQir=4k4AL zOb^BE-z#r~Nv&k21-<2usE$t&!50m`8*$!Pd?9A!` z>YkJafgkAhEpq%N{jQ9&tPWa^V9s7SLu2fnrviWEdRk2Ze7PTxA8mwSiwtNnfDf=^ zH5D@J5j@njR@|AkKl_wrR-u`I3W~@L%T?41&6YRK37)pg)F}tw1qTqp;v|d7M@zq_ zwMTqpumbtRtP*VdzFGrTzUKr?xVDu6pgt!qFo?XOi|=VnH){t~rNwJ*DI>4id0x@dch0D$1pSh`tS@2%)~`G| zHSTsh2PDF?^6waIh(E3YJE&92M__+SQfU=qH09MH)eR{Wp(Jv#0NP^5mdeE#VPqOu(mtbf=_b}?2_A+;z9=GbYL;ZMB z%BvyC(F?aia7$maP#zp`L*||8gE=7`NzNWCLkq@a47p}R%Zq4$AIY1>!b03p>D5`j#V-jRWpXyj za3eEN3TuqpEP~42PkBVjmaE&nNRl(v=cfx<@gCnDou3fe56bV;aA3srW>tUksAK6? zB@YmAI(RxB_sD!dHR*5j52cz(_3)<+KdD4?Qau72JXM{_iE2cs?%rlZyY1~^NxGZc zB5NzyzS)s--VYyc(z0@@k{_~Qw0w*f_5+yC90l6sIafI5P8EO+*L|e&%%^&8P+eV} zZ8$@F0-BS|Po9ccQhrsvPkMUYL-*jAlRJ zn-nGT}tjUF!DlukK&8+xQp&mq|sCT;Tle#zRQS? zk!zdrd~P48x42IGPS}l-A9ET}uJXw9)jD7AtrN@{A7^Z4+v~|#j!?+F@}NFYDDfwG*~%@D(mQ6{A6%j- zRj>|L($8J1oN+Ii38pNKK=99fsM>m=`*B2H+eEobH~MYtseQT*vjxDsO%hOJ%7wSg zEDt>6b~b7+Lp3v9U~;+1umaPxOUVnfcXaFuB-qYDc9mvE9a%*Of1hLI)1GYLrRW6W zz5@@AO}#nTmr|C$|6$4K858fZaZvj8vbba@1Li^lzq{#qgWZd<>S>nZK32pt+ESmw z0!3R12T7@|XXJk}th5r?)wn?ak%2ZzVvsvf&`nt;%#l)C_l%4qo&e#U%tZ3$FkCRX z!x_fP{%01I(d3(&q9!?EP_+7`Bf{oJ;#NuZ4An3pF7{ zpAC#{Q~PAKiR%$~18XBX%6PNfk@TNuIA~2Z96()h#@peHG>wv=Z5A ztAp%+pz#vzM+F3)|B1l!D=>}_KYekIqhs^;5a~aAQ~7ATMBWuPuiu;3zX>=I;T$wx z;wmQX_+c&S!%owD_EUb(6@Kp#{5`#T%P(HywsrTB!&-)`{o*A)t^aiK_psN$cjB}< z-{g^-A^XP&zVqJ~O`Jlt{_-cr_G>9euF$Z9aMIDQaW8*ncV1`ztvCBCks8i+v`bbj z5Ap1!#@~bfhtl5NaAaqw|6rQrp@h~P8lknNzS!o>VJ)}wX@pj_23LK~zh(dX5`z(q z&^kG0f;js7`oDFS_MDStyyMbEF@MYc_oWCy8liP{Mc6$0_w|1RFrh*;#W@ALU~>CE z2 { + await prisma.post.deleteMany({}) + await prisma.user.deleteMany({}) + + for (let index = 0; index < TOTAL - 1; index++) { + await prisma.user.create({ + data: { + email: `${Math.round(Math.random() * 1000)}${faker.internet.email()}`, + name: faker.internet.displayName(), + posts: { + create: { + title: faker.lorem.sentences(1), + content: faker.lorem.text(), + published: faker.datatype.boolean(), + }, + }, + }, + }) + + console.log(`Inserted ${index + 1}/${TOTAL} item.`) + } + + await prisma.user.create({ + data: { + name: 'Nikolas Burk', + email: 'niko@gmail.com', + posts: { + create: { + title: 'The great gatsby', + content: 'The story had a nice ending.', + }, + }, + }, + }) + + console.log(`Inserted ${5000}/${TOTAL} item.`) +} + +main().then(() => console.log('🌿 Seeding completed.')) diff --git a/optimize/optimize-repeated-query/script.ts b/optimize/optimize-repeated-query/script.ts new file mode 100644 index 000000000000..e3e9b521e92f --- /dev/null +++ b/optimize/optimize-repeated-query/script.ts @@ -0,0 +1,57 @@ +import { prisma } from './utils' + +// A `main` function so that we can use async/await +async function main() { + // A simple query to create the database connection as the database connection usually takes a lot of time + await prisma.post.findFirst({ + select: { + id: true, + }, + }) + + // Query 1 + await prisma.user.findFirst({ + select: { + name: true, + }, + }) + + // Query 2 + await prisma.user.findFirst({ + select: { + name: true, + }, + }) + + // Query 3 + await prisma.user.findFirst({ + select: { + name: true, + }, + }) + + // Query 4 + await prisma.user.findFirst({ + select: { + name: true, + }, + }) + + // Query 5 + await prisma.user.findFirst({ + select: { + name: true, + }, + }) +} + +main() + .then(async () => { + await prisma.$disconnect() + console.log('Done') + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) diff --git a/optimize/optimize-repeated-query/tsconfig.json b/optimize/optimize-repeated-query/tsconfig.json new file mode 100644 index 000000000000..86758c0f7a5d --- /dev/null +++ b/optimize/optimize-repeated-query/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "sourceMap": true, + "outDir": "dist", + "strict": true, + "lib": ["esnext"], + "esModuleInterop": true + } +} diff --git a/optimize/optimize-repeated-query/utils/db.ts b/optimize/optimize-repeated-query/utils/db.ts new file mode 100644 index 000000000000..49543d2c3750 --- /dev/null +++ b/optimize/optimize-repeated-query/utils/db.ts @@ -0,0 +1,10 @@ +import { PrismaClient } from '@prisma/client' +import { withOptimize } from '@prisma/extension-optimize' + +export const prisma = new PrismaClient().$extends( + withOptimize({ + dashboardUrl: "https://optimize-dev-pr606.prisma.workers.dev", + ingestionUrl: "https://optimize-ingestion-dev-pr606.prisma.workers.dev", + apiKey: process.env.OPTIMIZE_API_KEY!, + }), +) diff --git a/optimize/optimize-repeated-query/utils/index.ts b/optimize/optimize-repeated-query/utils/index.ts new file mode 100644 index 000000000000..1beb455f5e39 --- /dev/null +++ b/optimize/optimize-repeated-query/utils/index.ts @@ -0,0 +1 @@ +export * from './db' diff --git a/optimize/optimize-select-returning-all/.env.example b/optimize/optimize-select-returning-all/.env.example new file mode 100644 index 000000000000..90cfec3bf6c7 --- /dev/null +++ b/optimize/optimize-select-returning-all/.env.example @@ -0,0 +1,2 @@ +DATABASE_URL="" +OPTIMIZE_API_KEY="" diff --git a/optimize/optimize-select-returning-all/.gitignore b/optimize/optimize-select-returning-all/.gitignore new file mode 100644 index 000000000000..2484fd1582e2 --- /dev/null +++ b/optimize/optimize-select-returning-all/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +*.env +package-lock.json +prisma/migrations diff --git a/optimize/optimize-select-returning-all/README.md b/optimize/optimize-select-returning-all/README.md new file mode 100644 index 000000000000..9317bc5fa0b5 --- /dev/null +++ b/optimize/optimize-select-returning-all/README.md @@ -0,0 +1,134 @@ +# Prisma Optimize Example: Applying the recommendation to avoid over-fetching + +This repository demonstrates how to use [Prisma Optimize](https://pris.ly/optimize) to improve query performance using the `SELECT/RETURNING *` recommendation and avoiding over-fetching of data. + +## Prerequisites + +To successfully run the project, you will need the following: + +1. A **database connection string** supported by Prisma Optimize. +2. An Optimize API key, which you can obtain from your [Prisma Data Platform](https://pris.ly/pdp) account. + +## Getting started + +### 1. Clone the repository + +Clone the repository, navigate into it, and install the dependencies: + +```bash +git clone git@github.com:prisma/prisma-examples.git --depth=1 +cd prisma-examples/optimize/optimize-select-returning-all +npm install +``` + +### 2. Configure environment variables + +Create a `.env` file in the root of the project directory: + +```bash +cp .env.example .env +``` + +Next, open the `.env` file and update the `DATABASE_URL` with your database connection string and the `OPTIMIZE_API_KEY` with your Optimize API key: + +```env +# .env +DATABASE_URL="__YOUR_DATABASE_CONNECTION_STRING__" +# Replace __YOUR_DATABASE_CONNECTION_STRING__ with your actual connection string. +OPTIMIZE_API_KEY="your_secure_optimize_api_key" +``` + +- `DATABASE_URL`: The connection string to your database. +- `OPTIMIZE_API_KEY`: Reference the [Environment API Keys](https://www.prisma.io/docs/platform/about#environment) section in our documentation to learn how to obtain an API key for your project using Optimize. + +### 3. Set up the project + +Perform a database migration to prepare the project: + +```bash +npx prisma migrate dev --name init +``` + +If the database isn't seeded, run the following command to seed it: + +```bash +npx prisma db seed +``` + +If the database isn't seeded, run the following command to seed it: + +```bash +npx prisma db seed +``` + +### 4. Open the Optimize dashboard + +You can create [recordings](https://pris.ly/optimize-recordings) and view detailed insights into your queries, along with optimization [recommendations](https://pris.ly/optimize-recommendations), in the Optimize dashboard. To access the dashboard: + +1. Log in to your [Prisma Data Platform](https://console.prisma.io/optimize) account. If you haven't already, complete the onboarding process for Optimize by clicking the **Get Started** button. +2. If Optimize hasn't been launched yet, click the **Launch Optimize** button. +3. If you want to use a different workspace, navigate to your desired [Workspace](https://www.prisma.io/docs/platform/about#workspace), click the **Optimize** tab on the left sidebar to open the Optimize dashboard. Then, if Optimize is not yet launched, click the **Launch Optimize** button. + +### 5. Run the script + +Let's run the [script with unoptimized Prisma queries](./script.ts): + +1. In the Optimize dashboard, click the **Start new recording** button. +2. In the project terminal, run the project with: + + ```bash + npm run dev + ``` + +3. After the script completes, you'll see a log saying "Done." Then, in the Optimize dashboard, click the **Stop recording** button. +4. Observe the queries with high latencies highlighted in red, and review the recommendations in the **Recommendations** tab. You should see the recommendation **`SELECT/RETURNING *`** and click on it. + > For more insights on this recommendation, click the **Ask AI** button and interact with the [AI Explainer](https://pris.ly/optimize-ai-chatbot) chatbot. +5. To create a reference for comparison with other recordings, rename the recording to _Unoptimized queries_ by clicking the green recording label chip in the top left corner and typing "Unoptimized queries". + + ![Rename recording](./images/edit-recording-name-chip.png) + +### Optimize example: Applying the `SELECT/RETURNING *` recommendation + +Next, let’s follow the recommendation provided by Optimize to improve the performance of the queries: + +1. To enhance the performance of [**Query 1**](./script.ts) by addressing the `SELECT/RETURNING *` recommendation: + ```diff + // Query 1 + const result = await prisma.user.findFirst({ + where: { + name: 'Nikolas Burk', + }, + - include: { + - posts: { + - take: 10, + - }, + - }, + + select: { + + name: true, + + email: true, + + posts: { + + select: { + + id: true, + + }, + + take: 10, + + }, + + }, + }) + ``` +2. Click the **Start new recording** button to begin a new recording and check for any performance improvements. +3. In the project terminal, run the project with: + ```bash + npm run dev + ``` +4. After the script completes, click the **Stop recording** button. +5. Rename the recording to _Optimized queries_ by clicking the recording chip in the top left corner and typing "Optimized queries." + +You can now compare performance improvements by navigating to the "Optimized queries" and "Unoptimized queries" recording tabs and observing the query latency differences. + +--- + +## Next steps + +- Check out the [Optimize docs](https://pris.ly/d/optimize). +- Share your feedback on the [Prisma Discord](https://pris.ly/discord/). +- Create issues and ask questions on [GitHub](https://github.com/prisma/prisma/). diff --git a/optimize/optimize-select-returning-all/environment.d.ts b/optimize/optimize-select-returning-all/environment.d.ts new file mode 100644 index 000000000000..4dbd16ff6472 --- /dev/null +++ b/optimize/optimize-select-returning-all/environment.d.ts @@ -0,0 +1,10 @@ +declare global { + namespace NodeJS { + interface ProcessEnv { + DATABASE_URL: string + OPTIMIZE_API_KEY: string | undefined + } + } +} + +export {} diff --git a/optimize/optimize-select-returning-all/images/edit-recording-name-chip.png b/optimize/optimize-select-returning-all/images/edit-recording-name-chip.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4d482cfb4c21248e9429241d648139bbe47ca6 GIT binary patch literal 17291 zcmeIahg*|Nw?0fWh>8WaA|k~?m7?@sL`1rR^d>?=2}zLNyPcx+UPM3)1V|vE7Yi*E z0ZD|=loEQ779bG5c+UHty?@{Fm4D!HT}g&aduGj=HEZ4LhUa$;wONl{I7UZD$EtJZ zmN6Y2GmKXDKMJ6|4~f;b(9zM`xN2(N)zQ@CyXy%9xw-@C=!9N7K6vosj;K(FgTsRd z9X;2Ck9qnTKYJEq{2;8grI+thOFLh0OGcWF&E)yhlZ^L2&=uTk#eh%5@a-bSJ4(-D z77hZQV{@}cllJFJd`LR_n?m8&_^ahP?;OxSjGB&o!v+A{=H^q%Yj{id2|Hh+4H?X(ihhjDr{cDCsgPPz2RBMDM$CgDp;>S#l@1b;;~CAng0&IQ1$#Q@{= zn^79Gbd@KfBs2x07^2QZDZJWn^l~c~uUmNx|E^_**|J2=4}0>%9y9>2QKDf=tZiV&c;1D`*{9qOg%uX6dnS}4-WzrL2Z%=ceSyum7$ zEe!7RX~H~#e6r%##jjshJ;uk!r|jtjQZ&AG`(NE@zo}ey@%Hvml#uZA^Aq=z5{G#@ zOWaUUP>{GTDIqB-Mr$GF6#(^i@E3!6UHR`p{yokupqHbktB1EM49fRwT!)7+A8(b* zmw!$4KR^HdoIroqzh{Da{cBmY1xoy?k+>m#UE+Vnrgc^R^{wJvSAU?pp!ag|6NVJfS#H#2yISp)xWpqU!DJ1`LB-3 z62F%I4^jNLod4@vnxIvWDNFp%rl}rN3>}uIqf;x?xutR6pMH6a+5az7e9O;7-J3`G z^PhaFe>U(J*Rf}p8AN1neMaP2s2@3dH{i@!Caq87L0Xm9j$R&s^IdKv8y?lU6Gp0a zNa+EwCxlnj?~%ySW7)M{#9o-d&UibDIGX1^82yBf;V57DAKyG~9*H!X8&*&_v}Jhs zSw4Sk)Srj@Rl6Nd*J{mM!=g`5&vaUy?oV&D0j2(Lz~4yV|77@oYV-d{;3z9oq)Ixo zlOO2KRVRKuU9;2=lPCOfO6qpSw<)iiy^()3AmJ@KmnTzO37<;; zvdlqiu}LNxCJ?-XC8X|16V3FuJgJZNB`@6@;8Qky6Llq?G%e3{h^3(yne=NVEOSzv zbQYd4e0V`0SWNwheUZS%md!1^dm-8O=1u-jIbxcU{K7(}30F}r`jyGYMoL!q_Jmj%IpIObEEKAYN$wVf^5PpmTCEAlZ#f6jK#>|25S>3#gbWdgK zH!pSttZ=^G6v|%;Uw!dsxvJk_ihTK~n?>OkzNRPa2##HnzgeXO;68OK-Qnj*bOIER_9RD2RQBi*PLnCo(g zw(#9mrf)tv4(CtIX$r^gIi#D~L)KyjOzyG46Hi-qrTUxkcRr4$)t2KqhZ`~d92fxhbjctC2F;#J?Q_XO`7|^%5KT&cO9{zXGo4#b z(b6vWjo#>L4Tpfu%TpoN=wb3}{wsx`vM64KY)CI8Kd1T zODs`E_@CaQ+)~1G9v-$Nj#le(8~0m(yn)s8)Fbw;1RUY<-SZW2;y&3h>xbI}%XM%$ zj=!$i7V*43leaY7XpUGJH&ygo7P1dk#)Ts8RyHhpu#UT_lZRWc0H<~hjPs3;4A+Jf zSIMK&M+Y&*(a}uU4PmL7GV^g%gf+JbV-4fejZ`<8A3$8yuq3tkxp9G+Pk$bKC2aaR zGynL~V1P@7DS;Y&s{|I=bc(gcUN=d|fjBU|(KfKtr3YzN+;qdzNfqV5cABqEkKxs- zTCG_}o5*e2YedqZz6ZvpcdzFnv&!bPBw_0jA8s$_o>V_ON=wc`To6>@;i{PwY#n?` z?W>Wj`?ssDtr|#Apdp{~jT`r7du{oK;O*EBqPD-vSFi35qY~wem1q8}SrLggEyO5{ zu$EBz-nWBY9dB>poxP9c)9tXZ*Lo792Qbo+<=(^g^_hEBaxO3qsV1RgHx7bYV?q z*3{?ChAGy8TNM;&E&QppT0x2XNQLDSRaKj&-D$4cpXe3eT#6dp07sITh{tGv$je@! zUQ`5ud6%355;IC|4BF~+49R_EA9`K_zgg2Z#1pQ72Nz6uLaxmj-1nun5)8AI zI&oswGrL@#ed~ips)-_xOxL(^aRKs{mM=V;*SM3o4>1o}(G04*4F-L^LTixz@b^K3 ze9J!`>n#<%Gv+V!9kW7iimnpF8gyi;VM{@Unx8KL(}A7O)hO^=()M9 z6A$}TS8`R_MSJ%>dE?24t*rFd%EY>2Ye`$owqxb>^A}7QCnhP@* z8!242Q)YcLW!0`>P0>%E64<(y#i3IRNHCEH^#saEu|#=kp9tx1!u$A9R0DJ2xpwxT zB63S5+~mf%sD0B1o*^W#cLekKe5B?fuC{vKGX{nJp36Mm%Jol=oKgaw;wrr*u{*5ilvkY!@`}ULIgH0nOXvnGrinObSj5YLBhkdMz z-3m#5|5Wej!~}__zRWXO_f3Q;%pj_ql}m0FjfK|l^m0wB|Dex|SoD5xTKuHcw$aer z&~$2Qx?hkN37%M}tNjcaP7vcvP`XlE<5DjyEoUT87T?v5*fG>`yN>9>fTEh3U&;f(zcAWd0 z*M^zxyO!p?3d=exddgkXX9=Vxt&>F;y?y#0kp-`g#MrR@KwJkV$qbrfMR^VMj_IoW z_|AIaYbsZF9cH(H6#rGZU9@Xoap2q1q03_v3btBgF&1XGF{Zgv$9#Nk@iKM#!nH`k zjO^*4d||DNY;2cNMLm^jy?n5+wf9*QE6O^Cy02N(jFKMNhr*<+Dar%ZBJHN=v0asM z^YO5$EA_n)+Qn6+NIWtB$l9-7LP)414$kY{Xw_3Xq`n+}X@7}Yu13K%xjhHjrlN;x zoxk-da;V^3dntpNa<9=GwtR_UnGgL;;b$aHom#qLAF>;Jf_E*lN1*9F<*a9pwQQx- z?R$2KS4|&YE#5;BA9Z$iB3%bTmUZ6g@KNs+%RX~VvUsA&hvD_}`=yR`a*g(f`z&?p zuR3q`i0?YIlb+Gs-s$ovFm;gK4F?CfG*)kHcyqn;!S!w8h|QxZDH#Ia`9H*W3cq<9 z{k7-4==TIUP;PQEf1;pKO7b-?9KhGmqTJ5bm4J@Dmbd7R$4i?$3ou~h!Kvgu^rTdc3nE2sEsw?^My=K>zM z&L{=zs48*_3YJk;aqO9%2`31o5wHyaO0P57hA{@vURYCGR4 zx_YEgH$gZt>wMBf`?04(F@!cI=$MXw{2{(~<&iycf4F%@TJmM=Ao|Wtka49%7Gu1j zI=*JexU;|YwYJ=8?ZZ?i{Ol@rvdoJlOY^;BIqR<~TpJqxv=}COSF$Gh{&6vhpAMA= zKhw`2wzG+PE#*;|-m;Oz0City0o|Ks$hT?g&_G`RFqu26z<&tY;h>Sv=E{KnNA&mN zjKW`k));!GHTI*=CLy65?Y@V_5b7=VOp*J*H{I-qjd}X06MZBmBG|81_OL-$xo9mz zz2Ip=hp7@1lCG7Y-c)aMSnPOoJC=q$HP@QzAG&x3%kW7E--IoK^{^%F-435Dn-~=l zI3!@BV~7w{UzL4D62~8UzCy34ui{|Pv+P=bzVGNF)X(wxb9MNof;A6mN#A^i&wo)4 z^WypC!%P|9@zV{g)AiWuONX=!pE!EDVKdYE^R2@oYQ9%Tj*bJ?#%4wi^Fvx-Oh?Ce zd&(ZZIqZ<1?qJA|2!3?PuD6571>ar7@uK2iBw3rTT_ zFMnio#rhD=IYv)~-Jt;8U03*%mbZ|Zj*jk*t2o>~a(s@1b)$B3^Y$tZPddH+$IT4BqpruF z_-Ij6E}DjCsOMUTgof0fY1o{p|2XGHCFk%77%-G+ykt2O6Sk6|1BylrvKEereB zFMJ?XkG-t^ZUIc0O)#V z0w8G9f;;L-OQ%4KNf>hM5rX4SwqpC#5$Q}bDX3n$apz}9U}@ZUr`dCU7vnTrCYXdW zmtcM|JAXWxs-mw@ZDnNR&QwzvKk>fX)ge983iFEZEr#ipAtk}h4!$|p22PAdrOziM zyv}gWg?^FomWTn1h+X@dc*_J7u&~818HN`r4;l7a~KBc}IiowLt*gn!>QorIG^iM21pdj3lbkMB0;KNxl(B0ix{lK*R}uvL4E!` zP{ro8l7aerf&pGT<&v)0%f;4}cJVV7pEJU9dB47Mm#M8Ce{5WEUn?kn#9YO8g9j&J zG6eA6-&>2D-w@6W)>q&>@h9oa2ORkj_0j!yX>mBFr7Vb-b<&NuuV}b>cWOAt1vdtO zhRJCR!v$2XM9qc?J)ajIKnAO1_LuB0rXViM6kMBOIUf{fn%39uS^6PM;tRz_Eg;&P z5^_GmT0%~dG`Ld8o*AskCnjcVJUDQ*?tT(X|C!|<^&iS`=8^-O6B0I-nWDSZUE?!B zYQU?G;2Wcnac4o1n3AGkWYFM)_vm(xU{OxXbfmCr>XLGeec)G!GX`uqZoP=XkVr0H zH0p55+Tz>?Z})@aJKL76rrd=&t!^6Yn~~%eK^<_tFeIg|n%4;{4KooY`y^_kk{_7R9;Gh5rY+H=kihsom|h>!&$jZ*J;O`Je!6qu{4GHV2uYKi^L?IsS}c6{cJ2!eR@%K)zdEwm-$5&JXo0R(*(Uv z>lhlo?k^8}_41AG%!`2vJBVxl#(kFKN=?nAS^+k7-jh7~$@j{e1o5^*mTp7O)ZSmq zRCLUV37yj9yz%znUcAqJ_U{jVe~EPP=S7(H74g45PN*smS~ZJ5E~TN^R|GCbmw9Fc zj}+yygvKQfE2UyTjDeTpw_@MfeE|4q_Ee@1TdtADS$&VPX1QIL6uYLGBIuqFSma(F zikmFY!35uO&78Nc_XZB9G?>c@lF%9!tfzzGW>kwS@=kNzU%FpbXj?4TS~~T2P=>kH`lat@hMhupP`DenM>ZL#mb1JW3jIUIf5@U>(6=&Nmk0P!dr(<{_I&! zgTSRLTdkMN)fP`Jd8k!~kg}Q^Eg9vIb9NOF>c%^0*9A4-T^WIQ*&4TIJgseVo<`<_W0bLOr-fgV>=i4TIaaXQ8iwv2)t%iAD4q!<=vUak_t_+gTT3#CV}uwa{OcX z`i)Tbix)*rMNChJ#6A;x6r=52<0!UD$wfKMb(j|hyDPX3mp-RqRh_95)XVlEWH_tr z5Zq+lA~)e@+)ef7cQ+i?yj?>B9ZT+4Hl%%Kcj{NePQQGlhAm-T?EKPB(S5$US|HE( z^u2oE?I%7>@5TbOj@1}uNNR>=T-UPm-@U=%q_1yTVgk?Dk-YU5%mw@XEjIb-xQn{M zL0_Y(glX%(V+2WsvS885Gc`|lp`r|kRFsL@EJOv3&@D@{^M$y5C%&Qo#H-JTj%4}d zwzUv+Ei@665|1Gc@x4#6;(-K{3=Rh$!9= zBbQ+i^iv|r-NXMIC*~U+3UGh3Aw%K4s-FSZm6!UrO94?~%hzv-BSuC6uy)w4-i4&+ zsp0|@f32H_9&*-5{-Rq|x63YS2a08FJ&Z`wl0H1!*HOX93B&Fpxs~iZU77h53B4s*5o-bi2TU( z5X?#H8`;9p+xJ-bjx5~rI%#sulCU2uK|`c{Lf!2Qe|**EPqBiKxJ8du23x zR+iNKqm_4?U$6blyuvSe`9pQQT+^kz^!~Cw=zK=^Zfs_uU-Ko&m8TQ>Xcs}e@AyUg zi0FN0r?DqJwT2@#4z`@CHTDQd@Ne=SG}VYm)K+Ko9}_sm!7A%kGJS4laU^`a7_y7y z9=wfB&`d|?TuwBwoN_T4A(xy}`Q^~wj}Zdb&&d|M(tTC&Sag@@UVOr+1er9W7>*#n z0ASZrMV(Li=xVEtFL^Af>+ylr&86I$3D*aiRO`Qaeki*pgVtCrA*9?{?24UXOMDD3 zA8As&kNg(8y6xOUg~)oqGYR*h56L*mnRo4WX^9uvA4*17y8;j(z+&Ks3!_7x9V623 zf?JK^N65XQJ#4s^GFjFb@NLhtQugHPXJd?A#h<@cg-qPg@G5rYoTUo*+up_YAv~QF zxaRDDv-xCOLPFyrFw6>RORmYgvHys-)mp+2vbCp$Y)Pt%l}We#$gJjW=M`Gwb{{Sh zYjAE{<%|Oq>{Qwsm)5Sq!Y==OlsvPhcPf?3qBbzQVTZ~g=`_hGtGXZFRDpGlWZ^HTmkRi>Oa`CF5xX!LYl z{X|0HH6U^x)~NR=fv$q)Zz{_ z+1R%9D6+&m1f278YS|aF(WwoKkd-#043J)^VBy<4$JZ}<*CP|Jt$zz>%9)$6R^_G? zRF~M~H+akRnNQu`^ge1ni2NR=pL>N%|8zrTz$~JvGzy%%e!E$8eK1r0Mk}?Apx~OX(laSR6OW?g*FAE)oEth#oQEe0AOt_%L4o29 zEl6Kw^OfGv{p=E3R7TP@6RXf{=^^Ds7W9Mx-d6n5rKfOVm!Zdx)C{V~7J4}tmGb1Q zSzlPzPygRX`w^oIb-r+FZqQa4U?!^txH2A~=4wwaas;O5?qvYDIC=uwS8$V)rl4h< z5|_>85K!a%=BpddWJ!L%MPg|pxQiq{in`q^luK!bxamy(Kzp-q`&hZneka$7T^0Ja zGH@_UsuI(wU$$nAc0(_Tqo6RGPK(;FN%lC|?Q$chhwa4%AP{D$R|7Mgv5f)OikF)v>?erI{8UBCfy=mFDlthH7yg{R z#>ddKz$%M1c!3ypYLkF=EOybEspd&{$cQK*m>7HV7>f10w@h^$-|JxVHp@`&wzIxX z#*N2!tf&Mn3rj1R#HXVsVF7FDsZP5~N0314Uf%c3-6QpN5@ISudWmlT;aLsbgY~Dm z@u+k#v%#u))Jw9;TGG;R=K3-dal~IGkbcw7A+k85alV$XK90w{@QwcN3L{taP~WcK zZPNU4fd}RE4YI^+SL~MCUBA_e8?r8@sK5r+rI7V0nB*6xRVn>>%VIGZdI4K&d?SCF z#F4o)PELg|q0Qs;DE+*9sL<*S(hf1pA!p2VfLK{O+X) z?Drx3owKl(D8^hF`mP;Aj{XT^6Jze{WhLL?yfUh)s(WN&#xO~`(NAhtv|{lmPR5k3 z%DWCAwW%5_*{3hF&VMST$Xk^ZnuW4x{@_AVaC?66v$yI%ZYFOVy{p2pnTBM{f%$>p?9tVX_0{`)XGXwy`9q=`_Ek3xm#? z0X_B`@ye@nckvb@+F{Pp7NsFFLFQPeu&vEgYd^qG@yfUZUXO_@n*4)%Cw=N_V&7&+ zG;T=Yi|r%xevf6Tw=%5I%NG-4mi4kR+QFMRbG(8N?6rW4{34PFxjPs_X%^rz$qc&v zF4WilskxN53<|y67q5evc-ol?E^tp4BvG#*LU|4*-|N`w%4z{Ds}p0 zwaLu#S@v5}mNMV$+Dl1r{;X)cUG_U>nn-%1cvoxx_cPm)kB7yA{!kf`I(i!VSVxdLkOv1sGLnu`mLnZCLGA2 zZBW6@qvQokN622=(RvU9#OS7eI|_S2^ewj%J?mXpIy;om%K_=5#lu5}l&;cvN<2$W zlgccoISviNj|YenRafT*1zh$JF~K6md#$%n z2$!e6WrcXi*m7FNj8ZRCOk($DR_UT>Ult{GuX@`)aXz3xrk`)7o;OUa?^MXwv$wv+ zn6PfR(yjHY`VI3D*=gBwtRgy*va;Y1Z$jd*3+QvIGOV_zewo}$>}$H3Z6J%FihU^> zu7ZWE7M|cyz1_4wZE9Y$Xtq8R`&yHyviakP5o%cmwZ*;e?gA)5??2a(W&c*|S63$A zKEIEnn^}}N@jA^D=zX5+ZsQPBv5&!|p1urSaW>)o;~w--pKZ5~_wu9iZrOD71(%_4 z3;~$DA@yfao#dv?AfKbIF4)yTi6_=IXo|7(923D6(aBo&c8S$ z-Hd)XWEBJh(8xFYk&#>VxcfK15QA%2eCx|o;r3Yp2gwcyVqIzHhy5Ll@Y(~C_434w zuzT+ZZMaA%H5N&guX41X2M zPWEvgGD$2_X8a(`S%UnWv@^u_!-(Tl$~@s9*#gzHtZW4Yutc+*m zv+@jeSEPcO-c_>O*M7il7{V`q+3RgsL#)qRM`d!nt(@(ybkk_kb)E-$yo-u;+3;N9 zjNy?jB7IR1I!1>7wS*Ly;Fhwo#Eo4(9T+m!ZB;$eWUGd4Iyal!>|37lY2z;i%z&`u zS~p<^mRJ}JS;on#b2;MZLJ51_W7RjUOkMcwGZhSOfae!>>t}S6*aYt^EgifcbMy_P zyf-kouKWq{G;`u&TRK~3psgDhuc_T-eOH&_X|K@si>~!4KpfrbDGoJPtZWb>Hu&w- zzH3;8n!%QTk56-_%~vy#_iyngia;>?sp*aNkxpz|ZI~F^x_YSuaL25CjITIDvb(jl z^-X%W^k~3(weQLN{Bg&n$D9%f&m-2yyorc0fjM%NN;$~xq|{6v%V^z8-c0g^ zTZ3jIBE?_Br53)NDeqb)vwG~ifMa_X0!%C^(HQ*1sIw*b*+~E+$v;@#jgZ|(MpIe)Tk?YjTP95yDc=n0 zLg73U`|o>KY?tclGUglHe0nh-y^B-Ia1!?NWe$xavK0$VP@f>=?B8O+*S@@+uRQtwHxC1OLro#jgJ`h z74)S6pqmP#wcvPLYvs{k2d!q0yGcdqKTNwPl=dmJ(jmPv;iZLenFlMxzHHzPr( z1k>}j4NX$4tgo=&#VyT{LUUZ2WAX_bf9!wR3h zY)52xE_Tlfl%YQ^crMtTyr@v6P`+!2=fVY*3?n(xAC%`<_mvn(#aGX(LITHnv$Dd1{QoW5VZIk!OOZPY%pPesP9Fi1ZuY#ovT%Vp&0k4r;~ zy^8?S#|YBri|Dx^bpkAJ1)nA z(rt%l9@cj4%_){vISS@k4hK${AuOG-!-`jOgUq}X3LR`IKMN$9lJ`LnBl0<(6qH#B z3X*C=t}Ykeu@yJ!IMf~KaIuC7Zi zo51$F8UJT_)14q0roow(K~|_z`@pFy z)^@d&p=_-%!T&(Sq~*K;Kesa7jhx3!ipg6^A!~D^WQbV_=(}Qiq7|FD9)A#MRIz>D zg7ybCCNU7aur0F%qT_(MytSRhENaCJrWP1+5PMSYqQ=8`b9RKFks~Aqah~xhD z+BwTcP?EPH+n(YwKhw)jb=K1{fBBvde99er)@6v|Q!HG#B#%(37_);*HLWy*N6yzb z-!6F}dwykU(7b1Sh_`R+v9NX-?fS#;lX}?0n;{D?Yft|4UaK1P?0rc_Bo?0wg~ks` z_J#Rgfa1k_W$w}i({h|M0&ciu#PfHHy>@=4f(mIFZny`*H~`)46Y~=51{E3vVOGz` zM*`%DP(zvhtfH_xS=CUVOn|Sn5K6+KS!|+Y5f~^dxII-nMj*b4DW1_)@^QH$MHEd6 zOF_JPZUP$FykT;Z$2(bi)AuC$tgU*KuMFJ0dN_(BE2!qG4*{pZ&*|Mbf}fytpY7-& zoj7~#Q-*%met_>{-Mh07PciR#xBA%@e{Bq~F7PGigwQN&kgc=A)vLE2>WABB0(N;9 zLNZ7Dr!H69s|>|5Dx%;i zYj>(9BeDbpaqY1gdQgffBAZj@tZFiVB*Tpv>edx2^TYTO3jL=PW^|Inrgp=tPQOqqBvb?n5k&t z$2BwgAwEcGgq6{CZq0U)cdj0fe16~}>%I-N=5WV($2f-(Q7M;H&p}X@2V4HKJ$B-A z8S&HaXpU3ARyqbijMoa{ z71Iwv&5BiNoDU&Y3B)cEFd0DWW~dmYz!Eg*e8A5o2kS9C7*i<9!+(e=278A(A)(Ga zwnEFjYFGg8?nd44Nu{vw36W2n?Qa|zNmpO4;T7zN)Cve`mIe>IJ*iHCh`p1M9-i>( zNoAH!BTBOl^xgo*`s5B)=`TfU9VqfH!!hd%iX}Nfm~)S{Qxq~Izr^uilid8KwOX>U z07ADuEXaf8d@%^>>64*$uH^$!0t2H-r$Z?pC2Yz0_x4ASwD2$Ub7?D-s68ePzMn~j zf(4e`rxwSH`t0~}!xBwEZzARk4DerlV7rgch>;dU&JdFew#&qG^V2|M0F8fE#tV@crg zIu-K4=`>gB*5`K9bH$?}8jkXmEaa9VFDr;#O95Fw{@%yAo+aM!`&_3wJ%iN+xl3Zh zPVMK^zLc~toHtA#V=!z-B&tuMO9~7WW;cDuoNSFS?*77-72xEJEUIUVtqLv3ftCP3 zPt|rRl%-wLf)!SrcUEXL;;}319@Ag6ZCdHXp2GQW$~dlMWRemU1sq{mG&g$sJxEt^ zxeY8XWm&K1L__tTA^P5>KTOm=w?qS2XLjNB9gjKWRgROb(tbX~CMQdD%e+lT=Ifc4 zRz}qRe5(5PEdJ>`)6`ql-GRU+Mw&#N!^`dOn z;*guNX82x?PFP|w)=Q$1KZEr>C(^N*Vk(3Ztol_>2F6^yM!wc96x=pqf4zQir=4k4AL zOb^BE-z#r~Nv&k21-<2usE$t&!50m`8*$!Pd?9A!` z>YkJafgkAhEpq%N{jQ9&tPWa^V9s7SLu2fnrviWEdRk2Ze7PTxA8mwSiwtNnfDf=^ zH5D@J5j@njR@|AkKl_wrR-u`I3W~@L%T?41&6YRK37)pg)F}tw1qTqp;v|d7M@zq_ zwMTqpumbtRtP*VdzFGrTzUKr?xVDu6pgt!qFo?XOi|=VnH){t~rNwJ*DI>4id0x@dch0D$1pSh`tS@2%)~`G| zHSTsh2PDF?^6waIh(E3YJE&92M__+SQfU=qH09MH)eR{Wp(Jv#0NP^5mdeE#VPqOu(mtbf=_b}?2_A+;z9=GbYL;ZMB z%BvyC(F?aia7$maP#zp`L*||8gE=7`NzNWCLkq@a47p}R%Zq4$AIY1>!b03p>D5`j#V-jRWpXyj za3eEN3TuqpEP~42PkBVjmaE&nNRl(v=cfx<@gCnDou3fe56bV;aA3srW>tUksAK6? zB@YmAI(RxB_sD!dHR*5j52cz(_3)<+KdD4?Qau72JXM{_iE2cs?%rlZyY1~^NxGZc zB5NzyzS)s--VYyc(z0@@k{_~Qw0w*f_5+yC90l6sIafI5P8EO+*L|e&%%^&8P+eV} zZ8$@F0-BS|Po9ccQhrsvPkMUYL-*jAlRJ zn-nGT}tjUF!DlukK&8+xQp&mq|sCT;Tle#zRQS? zk!zdrd~P48x42IGPS}l-A9ET}uJXw9)jD7AtrN@{A7^Z4+v~|#j!?+F@}NFYDDfwG*~%@D(mQ6{A6%j- zRj>|L($8J1oN+Ii38pNKK=99fsM>m=`*B2H+eEobH~MYtseQT*vjxDsO%hOJ%7wSg zEDt>6b~b7+Lp3v9U~;+1umaPxOUVnfcXaFuB-qYDc9mvE9a%*Of1hLI)1GYLrRW6W zz5@@AO}#nTmr|C$|6$4K858fZaZvj8vbba@1Li^lzq{#qgWZd<>S>nZK32pt+ESmw z0!3R12T7@|XXJk}th5r?)wn?ak%2ZzVvsvf&`nt;%#l)C_l%4qo&e#U%tZ3$FkCRX z!x_fP{%01I(d3(&q9!?EP_+7`Bf{oJ;#NuZ4An3pF7{ zpAC#{Q~PAKiR%$~18XBX%6PNfk@TNuIA~2Z96()h#@peHG>wv=Z5A ztAp%+pz#vzM+F3)|B1l!D=>}_KYekIqhs^;5a~aAQ~7ATMBWuPuiu;3zX>=I;T$wx z;wmQX_+c&S!%owD_EUb(6@Kp#{5`#T%P(HywsrTB!&-)`{o*A)t^aiK_psN$cjB}< z-{g^-A^XP&zVqJ~O`Jlt{_-cr_G>9euF$Z9aMIDQaW8*ncV1`ztvCBCks8i+v`bbj z5Ap1!#@~bfhtl5NaAaqw|6rQrp@h~P8lknNzS!o>VJ)}wX@pj_23LK~zh(dX5`z(q z&^kG0f;js7`oDFS_MDStyyMbEF@MYc_oWCy8liP{Mc6$0_w|1RFrh*;#W@ALU~>CE z2 { + await prisma.post.deleteMany({}) + await prisma.user.deleteMany({}) + + for (let index = 0; index < TOTAL - 1; index++) { + await prisma.user.create({ + data: { + email: `${Math.round(Math.random() * 1000)}${faker.internet.email()}`, + name: faker.internet.displayName(), + posts: { + create: { + title: faker.lorem.sentences(1), + content: faker.lorem.text(), + published: faker.datatype.boolean(), + }, + }, + }, + }) + + console.log(`Inserted ${index + 1}/${TOTAL} item.`) + } + + await prisma.user.create({ + data: { + name: 'Nikolas Burk', + email: 'niko@gmail.com', + posts: { + create: { + title: 'The great gatsby', + content: 'The story had a nice ending.', + }, + }, + }, + }) + + console.log(`Inserted ${5000}/${TOTAL} item.`) +} + +main().then(() => console.log('🌿 Seeding completed.')) diff --git a/optimize/optimize-select-returning-all/script.ts b/optimize/optimize-select-returning-all/script.ts new file mode 100644 index 000000000000..79e0be46e749 --- /dev/null +++ b/optimize/optimize-select-returning-all/script.ts @@ -0,0 +1,42 @@ +import { prisma } from './utils' + +// A `main` function so that we can use async/await +async function main() { + // A simple query to create the database connection as the database connection usually takes a lot of time + await prisma.user.findFirst({ + select: { + name: true, + }, + }) + + // Query 1 + const result = await prisma.user.findFirst({ + where: { + name: 'Nikolas Burk', + }, + include: { + posts: { + take: 10, + }, + }, + }) + + console.log("We should query only the retrieved values:"); + + console.log({ + name: result?.name, + email: result?.email, + postIds: [...(result?.posts?.map((post) => post.id) ?? [])], + }) +} + +main() + .then(async () => { + await prisma.$disconnect() + console.log('Done') + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) diff --git a/optimize/optimize-select-returning-all/tsconfig.json b/optimize/optimize-select-returning-all/tsconfig.json new file mode 100644 index 000000000000..86758c0f7a5d --- /dev/null +++ b/optimize/optimize-select-returning-all/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "sourceMap": true, + "outDir": "dist", + "strict": true, + "lib": ["esnext"], + "esModuleInterop": true + } +} diff --git a/optimize/optimize-select-returning-all/utils/db.ts b/optimize/optimize-select-returning-all/utils/db.ts new file mode 100644 index 000000000000..e36241dd0511 --- /dev/null +++ b/optimize/optimize-select-returning-all/utils/db.ts @@ -0,0 +1,8 @@ +import { PrismaClient } from '@prisma/client' +import { withOptimize } from '@prisma/extension-optimize' + +export const prisma = new PrismaClient().$extends( + withOptimize({ + apiKey: process.env.OPTIMIZE_API_KEY!, + }), +) diff --git a/optimize/optimize-select-returning-all/utils/index.ts b/optimize/optimize-select-returning-all/utils/index.ts new file mode 100644 index 000000000000..1beb455f5e39 --- /dev/null +++ b/optimize/optimize-select-returning-all/utils/index.ts @@ -0,0 +1 @@ +export * from './db' diff --git a/optimize/optimize-unindexed-column/README.md b/optimize/optimize-unindexed-column/README.md index 91c005957656..b038d97746bd 100644 --- a/optimize/optimize-unindexed-column/README.md +++ b/optimize/optimize-unindexed-column/README.md @@ -49,6 +49,12 @@ Perform a database migration to prepare the project: npx prisma migrate dev --name init ``` +If the database isn't seeded, run the following command to seed it: + +```bash +npx prisma db seed +``` + ### 4. Open the Optimize dashboard You can create [recordings](https://pris.ly/optimize-recordings) and view detailed insights into your queries, along with optimization [recommendations](https://pris.ly/optimize-recommendations), in the Optimize dashboard. To access the dashboard: diff --git a/optimize/optimize-unindexed-column/prisma/seed.ts b/optimize/optimize-unindexed-column/prisma/seed.ts index cfe08136c408..e732a8417ca6 100644 --- a/optimize/optimize-unindexed-column/prisma/seed.ts +++ b/optimize/optimize-unindexed-column/prisma/seed.ts @@ -2,7 +2,7 @@ import { PrismaClient } from '@prisma/client' import { faker } from '@faker-js/faker' const prisma = new PrismaClient() -const TOTAL = 5000 +const TOTAL = 30 const main = async () => { await prisma.post.deleteMany({})