メインコンテンツへスキップ

評価

Prisma Accelerate は、高度なコネクションプーリングとグローバルなエッジキャッシュを通じて、データベースとのインタラクションを最適化します。そのコネクションプーラーは16のリージョンで利用可能であり、アプリケーションが需要に基づいてデータベースリクエストの負荷分散とスケーリングを行うのに役立ちます。

上記の情報を踏まえ、高負荷時のパフォーマンスを確認するために、Accelerate を高ボリュームで評価することをお勧めします。

Accelerate のコネクションプールはどのように負荷時のパフォーマンスを最適化するか

Prisma Accelerate は、動的なサーバーレスコネクションプーリングインフラストラクチャを採用しています。リクエストが行われると、Prisma Accelerate の設定時に割り当てられたリージョンのプロジェクトに対して、コネクションプールが迅速にプロビジョニングされます。このコネクションプールはアクティブな状態を維持し、確立されたデータベース接続を再利用しながら、多くの追加リクエストを処理します。コネクションプールは一定期間の非アクティブ状態が続くと切断されるため、Prisma Accelerate を評価する際には、継続的なトラフィックを流すことが重要です。

主な利点

  • 最適化されたクエリパフォーマンス: サーバーレスコネクションプーラーはクエリ負荷に適応し、ピーク時の需要においてデータベース接続が効率的に管理されることを保証します。

    Prisma Accelerate のコネクションプーラーは、データベース内のクエリのパフォーマンスを向上させることはできません。クエリパフォーマンスが問題となるシナリオでは、Prisma クエリの最適化、インデックスの適用、または Accelerate のエッジキャッシュの利用をお勧めします。

  • コネクションの再利用の最大化: 継続的なボリュームのクエリを実行することで、Accelerate コネクションプーラーのアクティブなインスタンスを維持するのに役立ちます。これによりコネクションの再利用が増加し、後続のクエリの応答時間が短縮されます。

このメカニズムを理解し活用することで、データベースクエリが大規模でも一貫して効率的に実行されることを保証できます。

Prisma Accelerate コネクションプーリングパフォーマンスの評価

以下に、サンプルモデルを使用してPrisma Accelerateを評価する方法の例を示します。

model Notes {
id Int @id @default(autoincrement())
title String
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}
import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

function calculateStatistics(numbers: number[]): {
average: number
p50: number
p75: number
p99: number
} {
if (numbers.length === 0) {
throw new Error('The input array is empty.')
}

// Sort the array in ascending order
numbers.sort((a, b) => a - b)

const sum = numbers.reduce((acc, num) => acc + num, 0)
const count = numbers.length

const average = sum / count
const p50 = getPercentile(numbers, 50)
const p75 = getPercentile(numbers, 75)
const p99 = getPercentile(numbers, 99)

return { average, p50, p75, p99 }
}

function getPercentile(numbers: number[], percentile: number): number {
if (percentile <= 0 || percentile >= 100) {
throw new Error('Percentile must be between 0 and 100.')
}

const index = (percentile / 100) * (numbers.length - 1)
if (Number.isInteger(index)) {
// If the index is an integer, return the corresponding value
return numbers[index]
} else {
// If the index is not an integer, interpolate between two adjacent values
const lowerIndex = Math.floor(index)
const upperIndex = Math.ceil(index)
const lowerValue = numbers[lowerIndex]
const upperValue = numbers[upperIndex]
const interpolationFactor = index - lowerIndex
return lowerValue + (upperValue - lowerValue) * interpolationFactor
}
}

async function main() {
const timings = []

// fire a query before going to the loop
await prisma.notes.findMany({
take: 20,
})

// we recommend evaluationg Prisma Accelerate with a large loop
const LOOP_LENGTH = 10000

for (let i = 0; i < LOOP_LENGTH; i++) {
const start = Date.now()
await prisma.notes.findMany({
take: 20,
})

timings.push(Date.now() - start)
}

const statistics = calculateStatistics(timings)
console.log('Average:', statistics.average)
console.log('P50:', statistics.p50)
console.log('P75:', statistics.p75)
console.log('P99:', statistics.p99)
}

main()
.then(async () => {
await prisma.$disconnect()
})
.catch((e) => {
await prisma.$disconnect()
process.exit(1)
})

Prisma Accelerate キャッシュパフォーマンスの評価

Prisma Accelerate のエッジキャッシュも、大量のクエリに最適化されています。キャッシュは繰り返し実行されるクエリに対して自動的に最適化されます。その結果、クエリ頻度が高まるにつれてキャッシュヒット率が増加します。また、クエリ結果をキャッシュに追加する処理はノンブロッキングであるため、短時間のクエリのバーストではキャッシュが十分に活用されない可能性があり、持続的な負荷が重要になります。

Accelerate のエッジキャッシュを評価するには、上記のスクリプトを以下のように変更してください。

import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

function calculateStatistics(numbers: number[]): {
average: number
p50: number
p75: number
p99: number
} {
if (numbers.length === 0) {
throw new Error('The input array is empty.')
}

// Sort the array in ascending order
numbers.sort((a, b) => a - b)

const sum = numbers.reduce((acc, num) => acc + num, 0)
const count = numbers.length

const average = sum / count
const p50 = getPercentile(numbers, 50)
const p75 = getPercentile(numbers, 75)
const p99 = getPercentile(numbers, 99)

return { average, p50, p75, p99 }
}

function getPercentile(numbers: number[], percentile: number): number {
if (percentile <= 0 || percentile >= 100) {
throw new Error('Percentile must be between 0 and 100.')
}

const index = (percentile / 100) * (numbers.length - 1)
if (Number.isInteger(index)) {
// If the index is an integer, return the corresponding value
return numbers[index]
} else {
// If the index is not an integer, interpolate between two adjacent values
const lowerIndex = Math.floor(index)
const upperIndex = Math.ceil(index)
const lowerValue = numbers[lowerIndex]
const upperValue = numbers[upperIndex]
const interpolationFactor = index - lowerIndex
return lowerValue + (upperValue - lowerValue) * interpolationFactor
}
}

async function main() {
const timings = []

// fire a query before going to the loop
await prisma.notes.findMany({
take: 20,
cacheStrategy: {
ttl: 30,
},
})

// we recommend evaluating Prisma Accelerate with a large loop
const LOOP_LENGTH = 10000

for (let i = 0; i < LOOP_LENGTH; i++) {
const start = Date.now()
await prisma.notes.findMany({
take: 20,
cacheStrategy: {
ttl: 30,
},
})

timings.push(Date.now() - start)
}

const statistics = calculateStatistics(timings)
console.log('Average:', statistics.average)
console.log('P50:', statistics.p50)
console.log('P75:', statistics.p75)
console.log('P99:', statistics.p99)
}

main()
.then(async () => {
await prisma.$disconnect()
})
.catch((e) => {
await prisma.$disconnect()
process.exit(1)
})
© . All rights reserved.