Ускорение медленных запросов Prisma с прямым выполнением SQL

Любите DX Prisma, но нужны меньшие накладные расходы на чтение для поддерживаемых форм запросов? Текущие JSON-результаты бенчмарков показывают среднее ускорение для Prisma v6, v7 и v8 на поддерживаемых чтениях в PostgreSQL и SQLite; для отдельных форм запросов результаты различаются.

Ускорить Prisma сейчас

  • Более быстрые поддерживаемые чтения
  • Без изменений запросов
  • Актуальные JSON-результаты бенчмарков
  • PostgreSQL и SQLite
Ваш вызов Prismauser.findMany
const users = await prisma.user.findMany({
  where: { status: 'ACTIVE' },
  include: { posts: true },
})
SQL, который выполняет prisma-sql
SELECT user_t.id, user_t.email, user_t.status,  COALESCE((    SELECT COALESCE(json_agg(json_build_object(      'id', posts_0.id,      'title', posts_0.title,      'authorId', posts_0."authorId"    )), '[]'::json)    FROM "public"."Post" posts_0    WHERE posts_0."authorId" = user_t.id  ), '[]'::json) AS postsFROM "public"."User" user_tWHERE user_t.status = $1
параметры ["ACTIVE"]1 запрос
Вывод createToSQL для схемы из двух моделей, переносы строк добавлены.
Покрытие Prisma
v6–v8
Матрица бенчмарков PostgreSQL и SQLite
Изменений запросов
0
Существующие вызовы Prisma остаются как есть
Файлов бенчмарков
6
Prisma v6/v7/v8 × PG/SQLite
Типобезопасность
100%
Тот же Prisma API

Почему Prisma работает медленно?

Понимание эволюции и характеристик производительности Prisma помогает объяснить, почему существует это расширение.

Путь Prisma: сначала DX, но на масштабе важна производительность

💡 Зачем нужно это расширение

Prisma сделала правильный архитектурный выбор для своих целей: типобезопасность, удобство разработки и единое поведение для разных баз данных. Но этот выбор создаёт накладные расходы, заметные на масштабе. Расширение не заменяет Prisma — оно оптимизирует чтения для команд, которым нужен DX Prisma и более быстрое выполнение там, где это важно.

  1. 🎯 2019: Рождение современной Prisma

    Prisma 2 вышла в 2019 году и изменила ландшафт ORM для TypeScript: типобезопасный доступ к базе данных и типы, генерируемые из схемы. Prisma представила архитектуру на основе движка, который транслирует запросы, валидирует их и даёт строгие гарантии, труднодостижимые в традиционных JavaScript ORM.

  2. ⚡ 2020–2022: Быстрый рост и расширение функций

    Prisma добавила мощные возможности: вложенные записи, транзакции и middleware. Функций стало больше, но каждый запрос по-прежнему платил архитектурную цену: запрос представляется, валидируется, выполняется, а результат приводится к формату API Prisma.

  3. 📊 2023: Накладные расходы заметны на масштабе

    По мере того как всё больше команд запускали Prisma под высокой нагрузкой, фиксированные накладные расходы на каждый запрос стали измеримыми. Сильнее всего это заметно на эндпоинтах с преобладанием чтений, в аналитике, агрегациях и на больших выборках. Эти накладные расходы — не баг, а цена гарантий и поведения API Prisma.

  4. 🚀 2024–2025: Prisma продолжает работу над производительностью

    Prisma выпустила крупные обновления, посвящённые производительности и изменениям движка. Но даже с улучшениями остаётся неизбежная цена разбора, валидации, планирования и формирования результата по сравнению с прямым выполнением SQL.

  5. 🎯 2026: выпуск расширения prisma-sql

    Расширение нацелено на производительность чтений. Оно обходит путь выполнения чтений Prisma для findMany, findFirst, findUnique, count, aggregate и groupBy, оставляя Prisma для записей, миграций, управления схемой и генерации типов. Перед внедрением проверьте совместимость с вашей версией Prisma.

Слой трансляции запросов

Prisma транслирует входные данные запроса в SQL для конкретной базы данных. Это обеспечивает единое поведение для разных баз и семантику API Prisma, но добавляет время обработки до того, как SQL попадёт в базу.

Валидация и гарантии типов

Prisma валидирует запросы по схеме и обеспечивает гарантии API. Это предотвращает классы ошибок, но добавляет накладные расходы на каждый запрос.

Формирование результата

Результаты приводятся к поведению API Prisma. Это удобно и консистентно, но добавляет задержку, особенно при больших выборках и сложных include.

Расширение дополняет Prisma, предлагая более быстрый путь для поддерживаемых запросов на чтение. Prisma остаётся для схемы, миграций, записей и генерируемых типов, а сгенерированный SQL выполняет выбранные горячие чтения через нативные клиенты базы данных.

Насколько быстрее? Реальные бенчмарки

Сравнение по последним JSON-результатам бенчмарков: Prisma v6, v7, v8, Drizzle ORM и prisma-sql

PostgreSQL

Кейсов запросов за запуск: 95
  • Prisma v6 (6.19.3)1.56× относительно Drizzle
    1.99×

    Prisma v6 (6.19.3): среднее ускорение 1.99× относительно Prisma

    Измерено кейсов запросов: 95, в среднем относительно Prisma30 сент. 2026 г.
  • Prisma v7 (7.10.0)1.51× относительно Drizzle
    1.47×

    Prisma v7 (7.10.0): среднее ускорение 1.47× относительно Prisma

    Измерено кейсов запросов: 95, в среднем относительно Prisma30 сент. 2026 г.
  • Prisma v8 (8.1.0-dev.1)1.63× относительно Drizzle
    1.54×

    Prisma v8 (8.1.0-dev.1): среднее ускорение 1.54× относительно Prisma

    Измерено кейсов запросов: 95, в среднем относительно Prisma30 сент. 2026 г.

SQLite

Кейсов запросов за запуск: 84
  • Prisma v6 (6.19.3)1.79× относительно Drizzle
    4.80×

    Prisma v6 (6.19.3): среднее ускорение 4.80× относительно Prisma

    Измерено кейсов запросов: 84, в среднем относительно Prisma30 сент. 2026 г.
  • Prisma v7 (7.10.0)1.84× относительно Drizzle
    2.29×

    Prisma v7 (7.10.0): среднее ускорение 2.29× относительно Prisma

    Измерено кейсов запросов: 84, в среднем относительно Prisma30 сент. 2026 г.
  • Prisma v8 (8.1.0-dev.1)1.63× относительно Drizzle
    2.10×

    Prisma v8 (8.1.0-dev.1): среднее ускорение 2.10× относительно Prisma

    Измерено кейсов запросов: 84, в среднем относительно Prisma30 сент. 2026 г.

Сформировано при сборке из последних файлов benchmark-results/*-latest.json. У столбцов общая шкала для обеих баз данных; янтарным отмечен лучший запуск для каждой базы. Результаты по отдельным формам запросов различаются.Таблица по запросамПосмотреть полные данные бенчмарка

Подробные результаты бенчмарков

Статистическое сравнение с использованием t-критерия Уэлча и порога практической значимости 1 мс

Эти результаты отражают режим выполнения, в котором запросы преобразуются в SQL при каждом обращении. В предварительно сгенерированном режиме SQL создаётся на этапе сборки — во время выполнения исполняются «сырые» параметризованные запросы без накладных расходов на преобразование.

PostgreSQLPrisma v6 (6.19.3)

В среднем 1.99x по сравнению с PrismaВ среднем 1.56x по сравнению с Drizzle35/95 статистически значимых побед60 в пределах порога шума
30 сент. 2026 г.
ТестPrismaprisma-sqlDrizzleУскорениеЗнач.CV%n
findMany basic0.529ms±0.0640.231ms±0.2340.271ms~1.00x≈198.0%50
findMany where =0.501ms±0.00690.208ms±0.00940.347ms~1.00x≈15.6%50
findMany where >=16.51ms±0.2675.67ms±0.3387.43ms2.91x1.31x D***21.0%50
findMany where IN0.657ms±0.1420.292ms±0.0170.492ms~1.00x≈20.3%50
findMany where null0.280ms±0.0200.167ms±0.0120.177ms~1.00x≈25.7%50
findMany ILIKE0.297ms±0.00970.168ms±0.00890.278ms~1.00x≈18.6%50
findMany AND2.72ms±0.1611.11ms±0.1111.45ms2.45x1.31x D***31.5%50
findMany OR13.98ms±0.2864.69ms±0.2215.88ms2.98x1.25x D***17.0%50
findMany NOT0.639ms±0.0130.274ms±0.00910.478ms~1.00x≈12.2%50
findMany orderBy4.50ms±0.2191.48ms±0.0751.76ms3.03x1.18x D***18.5%50
findMany pagination0.342ms±0.0320.171ms±0.0260.295ms~1.00x≈43.2%50
findMany select0.294ms±0.00940.181ms±0.00720.176ms~1.00x≈14.0%50
findMany relation some1.69ms±0.0980.999ms±0.064—~1.00x≈22.1%50
findMany relation every2.17ms±0.0961.47ms±0.078—~1.00x≈18.9%50
findMany relation none26.02ms±0.51710.06ms±0.511—2.59x***18.0%50
findMany nested relation1.76ms±0.0761.24ms±0.060—~1.00x≈18.0%50
findMany complex2.94ms±0.1091.46ms±0.0681.73ms2.01x1.18x D***17.2%50
findFirst0.378ms±0.0320.175ms±0.0140.350ms~1.00x≈28.0%50
findFirst skip0.328ms±0.1070.147ms±0.00640.301ms~1.00x≈15.2%50
findUnique id0.232ms±0.00970.102ms±0.00550.207ms~1.00x≈18.6%50
findUnique email0.210ms±0.00720.090ms±0.00440.179ms~1.00x≈17.1%50
count0.109ms±0.00330.063ms±0.00300.064ms~1.00x≈16.2%50
count where0.469ms±0.0150.247ms±0.0160.287ms~1.00x≈22.2%50
aggregate count0.215ms±0.00780.155ms±0.0042—~1.00x≈9.2%50
aggregate sum/avg0.305ms±0.0140.261ms±0.0053—~1.00x≈7.1%50
aggregate where0.446ms±0.01000.239ms±0.0058—~1.00x≈8.7%50
aggregate min/max0.305ms±0.0150.268ms±0.010—~1.00x≈13.2%50
aggregate complete0.381ms±0.00610.292ms±0.0072—~1.00x≈8.8%50
groupBy0.419ms±0.0240.344ms±0.013—~1.00x≈12.8%50
groupBy count0.422ms±0.01000.358ms±0.0050—~1.00x≈4.8%50
groupBy multi0.544ms±0.0130.442ms±0.052—~1.00x≈38.9%50
groupBy having0.505ms±0.0110.375ms±0.0086—~1.00x≈8.2%50
groupBy + where0.550ms±0.0110.294ms±0.0064—~1.00x≈7.8%50
_count via include0.679ms±0.0130.511ms±0.013—~1.00x≈8.9%50
_count via include + relations1.55ms±0.0370.666ms±0.017—~1.00x≈9.3%50
groupBy aggregates0.557ms±0.00970.465ms±0.0091—~1.00x≈6.9%50
groupBy min/max0.531ms±0.00800.441ms±0.0053—~1.00x≈4.2%50
include list + nested to-one1.46ms±0.0290.337ms±0.032—4.32x***30.2%50
include list + nullable to-one2.59ms±0.0811.65ms±0.056—~1.00x≈11.9%50
include posts4.25ms±0.2162.35ms±0.1205.77ms1.81x2.45x D***18.9%50
include profile0.635ms±0.8710.540ms±0.2410.648ms~1.00x≈104.7%50
include 3 levels4.48ms±0.1484.03ms±0.1474.58ms~1.00x≈13.6%50
include 4 levels5.61ms±0.1823.39ms±0.1324.65ms1.65x1.37x D***13.9%50
include + where4.04ms±0.1762.88ms±0.3995.51ms~1.00x≈46.7%50
include + select nested2.52ms±0.1391.96ms±0.1854.42ms~1.00x≈31.8%50
findMany startsWith0.270ms±0.0280.140ms±0.0140.314ms~1.00x≈35.4%50
findMany endsWith0.563ms±0.0150.216ms±0.00690.369ms~1.00x≈11.1%50
findMany NOT contains0.627ms±0.0220.250ms±0.1040.447ms~1.00x≈121.8%50
findMany LIKE0.245ms±0.00940.111ms±0.00690.250ms~1.00x≈21.9%50
findMany <25.55ms±0.3987.55ms±0.29210.60ms3.39x1.40x D***13.4%50
findMany <=26.43ms±0.3717.78ms±0.22010.97ms3.40x1.41x D***10.2%50
findMany >15.55ms±0.5995.21ms±0.3566.78ms2.99x1.30x D***24.2%50
findMany NOT IN0.644ms±0.0130.282ms±0.0110.487ms~1.00x≈13.4%50
findMany isNot null0.642ms±0.0140.336ms±0.0170.362ms~1.00x≈18.6%50
orderBy multi-field4.99ms±0.1901.55ms±0.0761.88ms3.22x1.21x D***17.0%50
orderBy relation to-one4.10ms±0.1353.08ms±0.090—1.33x***10.2%50
orderBy relation + scalar5.02ms±0.2583.63ms±0.205—1.39x***20.0%50
orderBy nullable relation4.08ms±0.3002.94ms±0.181—1.39x***21.1%50
orderBy deep relation5.43ms±0.1864.04ms±0.174—1.34x***14.9%50
orderBy deep relation + scalar6.34ms±0.1354.62ms±0.100—1.37x***7.8%50
distinct status8.84ms±0.3761.56ms±0.181—5.66x***36.9%50
distinct multi12.04ms±0.1712.50ms±0.073—4.81x***10.3%50
cursor composite tuple1.61ms±0.0251.13ms±0.017—~1.00x≈5.3%50
cursor composite desc1.75ms±0.0371.31ms±0.021—~1.00x≈5.8%50
cursor prefix of orderBy2.70ms±0.1881.66ms±0.082—1.63x***18.1%50
select + include1.60ms±0.1010.309ms±0.0210.568ms5.16x1.84x D***24.6%50
_count relation1.74ms±0.3411.67ms±0.781—~1.00x≈123.8%50
_count multi-relation0.257ms±0.0290.218ms±0.045—~1.00x≈62.4%50
_count inside include2.32ms±0.1261.55ms±0.124—~1.00x≈32.0%50
_count inside nested select4.64ms±0.2023.69ms±0.266—~1.00x≈24.3%50
_count deep include5.49ms±0.2473.98ms±0.158—1.38x***14.1%50
ILIKE special chars0.425ms±0.0330.193ms±0.022—~1.00x≈36.5%50
LIKE case sensitive0.263ms±0.0100.110ms±0.0078—~1.00x≈24.0%50
findMany Date range0.424ms±0.0120.190ms±0.0120.321ms~1.00x≈21.1%50
count Date range1.14ms±0.0470.925ms±0.0520.995ms~1.00x≈19.8%50
findMany Date gte0.403ms±0.0250.178ms±0.00580.303ms~1.00x≈11.6%50
depth-1 low-fan0.566ms±0.0210.447ms±0.102—~1.00x≈73.7%50
depth-1 mid-fan4.21ms±0.1102.34ms±0.178—1.80x***26.3%50
depth-1 high-fan4.16ms±0.1222.25ms±0.130—1.85x***20.4%50
depth-1 wide3.11ms±0.1141.78ms±0.166—1.75x***31.3%50
depth-1 unbound39.65ms±3.789.43ms±0.884—4.21x***29.1%50
depth-24.78ms±0.1533.54ms±0.187—1.35x***18.6%50
depth-2 paginated Project→tasks3.16ms±0.1492.68ms±0.161—~1.00x≈20.6%50
depth-2 high-fan3.84ms±0.1852.86ms±0.229—~1.00x≈28.7%50
depth-2 wide4.90ms±0.1763.08ms±0.176—1.59x***20.6%50
depth-2 unbound65.60ms±1.5217.60ms±0.479—3.73x***4.4%10
depth-3 unbound15.32ms±0.2818.38ms±0.354—1.83x***15.8%50
depth-3 paginated2.44ms±0.1562.34ms±0.253—~1.00x≈32.7%50
depth-4 unbound9.96ms±0.2686.14ms±0.266—1.62x***15.7%50
depth-4 paginated3.42ms±0.1612.42ms±0.175—~1.00x≈23.6%50
findFirst depth-22.91ms±0.1142.30ms±0.173—~1.00x≈25.9%50
findUnique depth-2 Project→tasks→comment3.27ms±0.1132.16ms±0.173—1.52x***27.5%50
complex nested select4.51ms±0.4283.01ms±0.777—~1.00x≈65.7%50
ultra deep query15.94ms±0.5465.83ms±0.361—2.73x***22.0%50
transaction: (3 operations)3.00ms±0.2751.41ms±0.246—2.14x***53.2%50
*** p < 0.001** p < 0.01*  p < 0.05ns статистически незначимо≈ в пределах порога шума 1 мс± 95% ДИCV% > 15% = высокая вариативность
Замерен режим выполнения. Предварительно сгенерированный режим полностью пропускает преобразование запроса в SQL во время выполнения — ожидайте меньшую задержку, чем показано здесь, особенно для сложных запросов, где стоимость преобразования относительно выше.

Методология

  • –Воспроизведение: npm run bench (BENCHMARK_JSON_OUTPUT=1 записывает JSON). Результаты сохраняются в benchmark-results/summary-.json; эта страница строится по v--latest.json.
  • –Каждый запрос выполняется на одной и той же базе данных для всех клиентов: Prisma, prisma-sql, Drizzle. Размер выборки для каждого теста указан в столбце n.
  • –Для каждой стороны указаны: среднее, медиана, stdDev, p95, p99, CV%. Значимость оценивается t-критерием Уэлча с практическим порогом 1 мс; планки погрешностей — 95% ДИ.
  • –Измерен режим выполнения: SQL преобразуется при каждом запросе. Предварительно сгенерированные (@optimize) запросы полностью пропускают преобразование и работают быстрее, чем показано.
  • –Оборудование и версии различаются между запусками — у каждого JSON-файла своя временная метка. Сравнивайте запуски, выполненные на одной машине.

Что работает быстрее, а что остаётся в Prisma

Все проверенные нами возможности Prisma Client в PostgreSQL и SQLite. Записи остаются в Prisma; чтения компилируются в SQL, если форма запроса поддерживается.

PostgreSQL
SQLite
Методы моделиОпции запросаФильтрыСортировкаАгрегатыAPI клиентаТипы результатов

25 из 73 проверенных возможностей полностью ускорены в PostgreSQL. Могут вернуть результат, отличный от Prisma: 19; в полной карте каждая из них указана с причиной.

Количество возможностей по статусам
СтатусPostgreSQLSQLite
Ускорено2521
Частично66
Откат на Prisma97
Выполняется в Prisma77
Может отличаться1917
Недоступно24
Только в prisma-sql52
Нет в Prisma06
Не проверено03
Открыть полную карту паритета
ПровереноКак мы гарантируем корректность?Поддерживаемые запросы проверяются на соответствие Prisma в PostgreSQL и SQLite, а отчёты бенчмарков охватывают Prisma v6, v7, v8, Drizzle и сгенерированный SQL.Методология тестирования

Как это оптимизирует Prisma

Обходите путь выполнения чтений Prisma, сохраняя API и типы

  1. Перехват запросов Prisma

    Расширение перехватывает операции чтения (findMany, findFirst, findUnique, count, aggregate, groupBy) до выполнения

    generated/sql, фрагмент
    query: {
      $allModels: {
        async $allOperations({ model, operation, args, query }) {
          if (!ACCELERATED_METHODS.has(operation)) {
            return query(args)
          }
          return executeAccelerated(model, operation, args, query)
        },
      },
    }
  2. Генерация оптимизированного SQL

    Преобразует запросы Prisma в быстрый параметризованный SQL с оптимизированными JOIN

    SQL для PostgreSQL
    SELECT user_t.id, user_t.email, user_t.status,
      COALESCE((
        SELECT COALESCE(json_agg(json_build_object(
          'id', posts_0.id,
          'title', posts_0.title,
          'authorId', posts_0."authorId"
        )), '[]'::json)
        FROM "public"."Post" posts_0
        WHERE posts_0."authorId" = user_t.id
      ), '[]'::json) AS posts
    FROM "public"."User" user_t
    WHERE user_t.status = $1
    
    -- params ["ACTIVE"]
  3. Прямое выполнение

    Выполняет запросы через postgres.js или better-sqlite3, обходя накладные расходы чтения Prisma

    generated/sql, фрагмент
    if (DIALECT === 'postgres') {
      await client.unsafe(sql, normalizedParams).forEach((row) => {
        results.push(row)
      })
      return results
    }
    
    const stmt = getOrPrepareStatement(client, sql)
    return stmt.all(...normalizedParams)
  4. Возврат совместимых результатов

    Результаты соответствуют ожидаемому формату Prisma. Типы, IntelliSense и существующий код запросов остаются без изменений

    users.ts
    const users = await prisma.user.findMany({
      where: { status: 'ACTIVE' },
      include: { posts: true },
    })
    
    users[0].email
    users[0].posts[0].title
    
    // Те же выводимые типы, что и в Prisma Client.
    // Значения Decimal, BigInt и DateTime могут
    // отличаться; каждый случай указан в карте паритета.
Проверенная безопасностьКак мы предотвращаем SQL-инъекции?Многоуровневая валидация: привязка параметров, проверка полей по схеме и текущий набор тестов безопасностиПодробнее о безопасности

Почему стоит выбрать это расширение Prisma?

Скорость выполнения чистого SQL для чтений при сохранении удобства разработки с Prisma

Мгновенное ускорение Prisma
Одноразовая настройка ускоряет чтения Prisma. Без рефакторинга, миграции и простоев.
Типы Prisma сохраняются
Полная поддержка TypeScript сохраняется. Вывод типов, автодополнение и проверки на этапе компиляции остаются при ускорении чтений.
Решение, проверенное в продакшене
Текущие тесты паритета проверяют поддерживаемые чтения на последних версиях Prisma. Используйте в продакшен-приложениях после проверки совместимости с вашей версией Prisma и нагрузкой.
Поддержка нескольких баз данных
Оптимизируйте чтения Prisma на PostgreSQL (включая Neon, Supabase) и SQLite.
Вариант с предварительной компиляцией
Опциональный генератор создает SQL во время сборки, снижая накладные расходы до микросекунд для самых горячих запросов.
Готово для serverless (Node-рантаймы)
Работает в serverless Node-рантаймах. Поддержка Edge зависит от ограничений рантайма и выбранного драйвера.

Не только быстрые чтения

prisma-sql добавляет возможности, которых нет в Prisma Client. Те же типы, тот же стиль кода.

$batch

N запросов дашборда за одно обращение к базе

Объединяйте независимые чтения в одно обращение к PostgreSQL. Типизированный результат-объект, без жонглирования Promise.all.

const dash = await prisma.$batch((b) => ({
  users: b.user.count(),
  posts: b.post.findMany({ take: 10 }),
  stats: b.task.aggregate({ _count: true }),
}))

@optimize

Заранее подготовьте SQL для самых горячих запросов

Добавьте аннотацию к модели в schema.prisma. При генерации точный SQL создаётся заранее; запросы подходящей формы во время выполнения полностью пропускают преобразование.

/// @optimize {
///   "method": "findMany",
///   "query": {
///     "where": { "status": "$status" },
///     "take": "$take"
///   }
/// }
model User { ... }

Планировщик кардинальности

Стратегию выбирают данные, а не догадки

Собранная статистика связей управляет переключением стратегий: плоские JOIN, коррелированные подзапросы или сегментированная загрузка через WHERE IN. Большие дочерние таблицы никогда не вызывают сканирование для каждого родителя.

prisma-sql-collect-stats \
  --output dist/planner.generated.js \
  --prisma-client dist/client/index.js

Когда производительность Prisma важнее всего

Типичные сценарии, где это расширение даёт реальный эффект

Аналитика и отчетность

Агрегации и операции groupBy в Prisma заметно выигрывают от прямого выполнения SQL

  • 5× быстрее groupBy для отчетов
  • Быстрее aggregate-запросы
  • Метрики в реальном времени с меньшей задержкой

Высоконагруженные API

Накладные расходы на каждый запрос накапливаются под нагрузкой, особенно на эндпоинтах с преобладанием чтений

  • Меньше время отклика API
  • Больше запросов на инстанс
  • Снижение затрат на инфраструктуру

Бессерверные функции

В serverless важна каждая миллисекунда: снижайте задержку чтений там, где это важно

  • Лучшие p95/p99 на чтениях
  • Меньше затрат за счёт более быстрых чтений
  • Быстрее чтения без рефакторинга

Мобильные бэкенды

Пользователи замечают задержки: более быстрые чтения сразу улучшают воспринимаемый UX

  • Быстрее загрузка ленты
  • Быстрее пагинация
  • Более отзывчивые взаимодействия

Оптимизируйте Prisma за 3 шага

Ускорьте чтения Prisma менее чем за 60 секунд

  1. Установите расширение Prisma

    Terminal
    # PostgreSQL
    npm install prisma-sql postgres
    
    # SQLite
    npm install prisma-sql better-sqlite3
  2. Добавьте расширение к Prisma Client

    schema.prisma
    generator client {
      provider = "prisma-client"
    }
    
    generator sql {
      provider = "prisma-sql-generator"
    }
    Terminal
    npx prisma generate
    db.ts
    import { PrismaClient } from '@prisma/client'
    import { speedExtension, type SpeedClient } from './generated/sql'
    import postgres from 'postgres'
    
    const sql = postgres(process.env.DATABASE_URL!)
    const basePrisma = new PrismaClient()
    
    export const prisma = basePrisma.$extends(
      speedExtension({ postgres: sql }),
    ) as SpeedClient<typeof basePrisma>
  3. Используйте Prisma как обычно

    users.ts
    const users = await prisma.user.findMany({
      where: { status: 'ACTIVE' },
      include: { posts: true },
    })

SQLite: передайте speedExtension({ sqlite: db }) с базой данных better-sqlite3.Полное руководство по настройке

Часто задаваемые вопросы о производительности Prisma

Частые вопросы об оптимизации чтений Prisma

Почему у Prisma есть накладные расходы?

Prisma добавляет накладные расходы, потому что реализует гарантии API: валидацию по схеме, согласованное поведение запросов и формирование результата. Эти слои дают отличный DX, но стоят времени по сравнению с прямым выполнением SQL.

Как оптимизировать запросы Prisma?

Оптимизируйте нагрузки Prisma с преобладанием чтений, добавив это расширение. Оно выполняет операции чтения через прямой SQL с помощью postgres.js или better-sqlite3, сохраняя API и типы Prisma. Настройка — небольшое изменение инициализации, рефакторинг существующих запросов не нужен.

Prisma медленнее, чем чистый SQL?

Для многих нагрузок на чтение — да. По сравнению с выполнением чистого SQL есть архитектурные накладные расходы. Расширение стремится сохранить DX Prisma и снизить задержку чтений за счёт прямого выполнения SQL.

Могу ли я ускорить Prisma без изменения существующих запросов?

Да. Добавьте расширение один раз при инициализации Prisma Client и оставьте существующий код запросов без изменений. Ускоряются чтения, при этом API, типы и схема остаются прежними.

Работает ли это в продакшене?

Да, оно рассчитано на использование в продакшене на поддерживаемых путях чтения. Всегда проверяйте совместимость с вашей версией Prisma и запускайте собственные регрессионные тесты перед внедрением.

Что вызывает медленные агрегации Prisma?

Агрегации и groupBy часто усиливают фиксированные накладные расходы (обработка запроса и формирование результата) и могут работать с большими промежуточными данными. Это расширение генерирует SQL напрямую и обычно снижает задержку на таких эндпоинтах.

Готовы ускорить Prisma?

Посмотрите актуальную таблицу бенчмарков для поддерживаемых чтений в PostgreSQL и SQLite