在 Prisma Postgres 中缓存查询
Prisma Postgres 支持内置查询缓存,以减少数据库负载并提升查询性能。你可以使用所有读取查询中可用的 cacheStrategy
选项配置缓存行为。
¥Prisma Postgres supports built-in query caching to reduce database load and improve query performance. You can configure cache behavior using the cacheStrategy
option available in all read queries.
此功能由通过 Prisma 加速 启用的内部缓存层提供支持,但除非你使用自己的数据库,否则你无需直接与 Accelerate 交互。
¥This feature is powered by an internal caching layer enabled through Prisma Accelerate, but you do not need to interact with Accelerate directly unless you're using your own database.
缓存策略
¥Cache strategies
对于 Prisma 客户端中的所有读取查询,你可以定义 cacheStrategy
参数来配置缓存行为。缓存策略允许你定义缓存的两个主要特性:
¥For all read queries in Prisma Client, you can define the cacheStrategy
parameter that configures cache behavior. The cache strategy allows you to define two main characteristics of the cache:
-
生存时间 (TTL):缓存响应被视为新鲜状态的持续时间(以秒为单位)。
¥Time-to-live (TTL): Duration in seconds a cached response is considered fresh.
-
重新验证时过期 (SWR):在后台刷新缓存期间,过时的缓存响应被视为可接受的持续时间(以秒为单位)。
¥Stale-while-Revalidating (SWR): Duration in seconds a stale cache response is considered acceptable while the cache is refreshed in the background
生存时间 (TTL)
¥Time-to-live (TTL)
生存时间 (TTL) 决定了缓存数据在多长时间内被视为新鲜。通过以秒为单位指定 ttl
,你可以控制缓存中数据保持有效的时长。执行读取查询时,如果缓存响应在 ttl
限制范围内,Prisma Client 将从缓存中检索数据,而无需查询数据库。如果缓存数据不可用或已过期,Prisma 客户端会查询数据库并将结果存储在缓存中以供将来的请求使用。
¥Time-to-Live (TTL) determines how long cached data is considered fresh. By specifying the ttl
in seconds, you can control the duration for which data in the cache remains valid. When a read query is executed, if the cached response is within the ttl
limit, Prisma Client retrieves the data from the cache without querying the database. If the cached data is not available or has expired, Prisma Client queries the database and stores the results in the cache for future requests.
在 cacheStrategy
中使用 ttl
,并指定查询的 TTL(以秒为单位):
¥Use ttl
in cacheStrategy
and specify the TTL of the query in seconds:
await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
},
});
如果指定的 TTL 为 60 秒,则大多数请求将在整个 TTL 持续时间内导致缓存命中:
¥With a specified TTL of 60 seconds, the majority of requests will result in a cache hit throughout the TTL duration:
TTL 有助于减少数据库负载和不需要频繁更新的数据的延迟。
¥TTL is useful for reducing database load and latency for data that does not require frequent updates.
使 TTL 失效并保持缓存查询结果为最新
¥Invalidate the TTL and keep your cached query results up-to-date
如果你的应用需要实时或近实时数据,缓存失效功能可确保用户看到最新的数据,即使在使用较大的 ttl
(Time-To-Live)时也是如此。通过使缓存失效,你可以绕过延长的缓存周期,以便在需要时显示实时数据。
¥If your application requires real-time or near-real-time data, cache invalidation ensures that users see the most current data, even when using a large ttl
(Time-To-Live). By invalidating your cache, you can bypass extended caching periods to show live data whenever it's needed.
例如,如果仪表板显示客户信息,并且客户的联系方式发生变化,TTL(生存时间)设置可确保缓存在设定的时长后自动过期。这允许系统在下次访问时仅刷新更新的数据,确保支持人员始终看到最新信息,而无需手动刷新缓存。
¥For example, if a dashboard displays customer information and a customer’s contact details change, TTL (Time-To-Live) settings ensure the cache automatically expires after a set duration. This allows the system to refresh only the updated data at the next access, ensuring support staff always see the latest information without manually refreshing the cache.
但是,在 TTL 到期前需要立即更新的情况下,缓存失效功能允许系统主动清除缓存中的特定数据。这将强制立即刷新更新后的信息,因此支持人员始终拥有最新详细信息,而无需等待 TTL 触发。
¥However, in cases where immediate updates are required before the TTL expires, cache invalidation allows the system to proactively clear specific data from the cache. This forces a refresh of the updated information instantly, so support staff always have the most current details without waiting for the TTL to trigger.
要使缓存的查询结果无效,你可以添加标签,然后使用 $accelerate.invalidate
API。
¥To invalidate a cached query result, you can add tags and then use the $accelerate.invalidate
API.
要使以下查询无效,你需要在 $accelerate.invalidate
API 中提供缓存标签:
¥To invalidate the query below, you need to provide the cache tag in the $accelerate.invalidate
API:
await prisma.user.findMany({
cacheStrategy: {
ttl: 60,
tags: ["findMany_users"],
},
});
// This is how you would invalidate the cached query above.
await prisma.$accelerate.invalidate({
tags: ["findMany_users"],
});
Stale-While-Revalidate (SWR)
Stale-While-Revalidate (SWR) 允许你控制 Prisma Postgres 在后台获取新数据的同时,可以保留过时的缓存数据的时间。执行读取查询时,Prisma Postgres 会根据 swr
时长检查缓存响应的时长。如果缓存数据在 swr
限制范围内,Prisma Postgres 会提供过时的数据,同时通过从数据库获取最新数据来刷新缓存。
¥Stale-While-Revalidate (SWR) allows you to control how long Prisma Postgres can serve stale cache data while fetching fresh data in the background. When a read query is executed, Prisma Postgres checks the age of the cached response against the swr
duration. If the cache data is within the swr
limit, Prisma Postgres serves the stale data while simultaneously refreshing the cache by fetching the latest data from the database.
在 cacheStrategy
中使用 swr
,并指定查询的 SWR(以秒为单位):
¥Use swr
in cacheStrategy
and specify the SWR of the query in seconds:
await prisma.user.findMany({
cacheStrategy: {
swr: 60,
},
});
当指定 SWR 为 60 秒时,缓存将提供过时的数据,直到每次请求后缓存在后台自行刷新:
¥When specifying a SWR of 60 seconds, the cache serves stale data until the cache refreshes itself in the background after each request:
使无效 SWR 并保持缓存查询结果为最新
¥Invalidate the SWR and keep your cached query results up-to-date
如果你的应用需要实时或近实时数据,缓存失效功能可确保用户看到最新的数据,即使在使用较大的 swr
(Stale-While-Revalidate)时也是如此。通过使缓存失效,你可以绕过延长的缓存周期,以便在需要时显示实时数据。
¥If your application requires real-time or near-real-time data, cache invalidation ensures that users see the most current data, even when using a large swr
(Stale-While-Revalidate). By invalidating your cache, you can bypass extended caching periods to show live data whenever it's needed.
例如,考虑一个显示仓库中产品库存水平的仪表板。使用 SWR(Stale-While-Revalidate)设置,仪表板可以立即显示最新的已知股票数据,即使数据略有过时,同时后台会获取新数据。这可确保员工无需等待即可继续使用最新信息,库存水平会在重新验证完成后立即更新。
¥For example, consider a dashboard that displays stock levels for products in a warehouse. With SWR (Stale-While-Revalidate) settings, the dashboard can immediately display the last known stock data, even if it’s slightly outdated, while new data is fetched in the background. This ensures that staff can continue working with recent information without waiting, with the stock levels updating as soon as revalidation completes.
但是,在需要立即更新库存数据的情况下(例如,如果产品库存不足且数量需要实时准确),缓存失效功能允许系统主动清除缓存中的特定数据。这将强制立即刷新最新的库存数据,因此工作线程始终拥有最新信息,而无需等待 SWR 完成重新验证。
¥However, in cases where stock data needs to be updated immediately—for instance, if a product is low in stock and the count needs real-time accuracy—cache invalidation allows the system to proactively clear specific data from the cache. This forces a refresh of the latest stock data instantly, so staff always have the most up-to-date information without waiting for SWR to complete the revalidation.
要使缓存的查询结果无效,你可以添加标签,然后使用 $accelerate.invalidate
API。
¥To invalidate a cached query result, you can add tags and then use the $accelerate.invalidate
API.
要使以下查询无效,你需要在 $accelerate.invalidate
API 中提供缓存标签:
¥To invalidate the query below, you need to provide the cache tag in the $accelerate.invalidate
API:
await prisma.user.findMany({
cacheStrategy: {
swr: 60,
tags: ["findMany_users"],
},
});
// This is how you would invalidate the cached query above.
await prisma.$accelerate.invalidate({
tags: ["findMany_users"],
});
选择缓存策略
¥Selecting a cache strategy
缓存可以帮助你缩短查询响应时间并减少数据库负载。但是,这也意味着你可能会向客户端提供过时的数据。是否接受提供过时数据以及在多大程度上接受过时数据取决于你的用例。ttl
和 swr
是可以用来调整缓存行为的参数。
¥Caching helps you improve query response times and reduce database load. However, it also means you might serve stale data to the client. Whether or not serving stale data is acceptable and to what extent depends on your use case. ttl
and swr
are parameters you can use the tweak the cache behavior.
使用 TTL 的缓存策略
¥Cache strategy using TTL
在可接受陈旧缓存数据的情况下,使用 TTL 来减少数据库负载。
¥Use TTL to reduce database load when stale cached data is acceptable.
用例:电商应用中的产品目录
¥Use case: Product catalog in e-commerce applications
假设一个电商应用的产品目录不经常变化。通过设置 ttl
(例如 1 小时),Prisma 客户端可以在该小时内为后续用户请求提供缓存的产品数据,而无需访问数据库。这将显著降低数据库负载并缩短产品列表页面的响应时间。
¥Consider an e-commerce application with a product catalog that doesn't frequently change. By setting a ttl
of, let's say, 1 hour, Prisma Client can serve cached product data for subsequent user requests within that hour without hitting the database. This significantly reduces the database load and improves the response time for product listing pages.
何时使其失效:如果目录有重大更新,例如重大价格变动或产品库存调整,则会立即返回 缓存应该失效,以防止客户看到过时的信息。
¥When to invalidate: If there are critical updates to the catalog, such as a major price change or product availability adjustment, the cache should be invalidated immediately to prevent customers from seeing outdated information.
缓存使用 SWR 的缓存策略
¥Cache strategy using SWR
使用 SWR 快速响应请求,并尽量减少陈旧数据。虽然它不会减少数据库负载,但可以显著缩短响应时间。
¥Use SWR to respond quickly to requests with minimal stale data. While it does not reduce database load, it can improve response times significantly.
用例:社交媒体平台中的用户资料
¥Use case: User profile in social media platforms
想象一个用户个人资料被频繁访问的社交媒体平台。通过利用持续时间为 5 分钟的 swr
,Prisma Postgres 可以快速提供缓存的用户个人资料信息,从而减少个人资料页面的延迟。同时,它会在后台在每次请求后刷新缓存,确保对配置文件所做的任何更新最终都会反映在后续请求中。
¥Imagine a social media platform where user profiles are frequently accessed. By leveraging swr
with a duration of, let's say, 5 minutes, Prisma Postgres can serve the cached user profile information quickly, reducing the latency for profile pages. Meanwhile, in the background, it refreshes the cache after every request, ensuring that any updates made to the profile are eventually reflected for subsequent requests.
何时使其失效:如果用户对其个人资料进行了重大更新,例如更改个人资料图片或个人简介,缓存应立即处于 invalidated 状态,以确保关注者无需等待 SWR 刷新即可看到最新更新。
¥When to invalidate: If a user makes significant updates to their profile, such as changing their profile picture or bio, the cache should be invalidated immediately to ensure that followers see the latest updates without waiting for the SWR refresh.
使用 TTL + SWR 的缓存策略
¥Cache strategy using TTL + SWR
为了获得极快的响应时间并减少数据库负载,请同时使用 TTL 和 SWR。你可以使用此策略来微调应用对陈旧数据的容忍度。
¥For very fast response times and reduced database load, use both TTL and SWR. You can use this strategy to fine-tune your application’s tolerance for stale data.
在 cacheStrategy
中使用 ttl
和 swr
,并指定查询的 TTL 和 SWR(以秒为单位):
¥Use ttl
and swr
in cacheStrategy
and specify the TTL and SWR of the query in seconds:
await prisma.user.findMany({
cacheStrategy: {
ttl: 30,
swr: 60,
},
});
当指定 TTL 为 30 秒且 SWR 为 60 秒时,缓存将在最初的 30 秒内提供新数据。随后,它会提供过时的数据,直到缓存在每次请求后在后台自行刷新:
¥When specifying a TTL of 30 seconds and SWR of 60 seconds, the cache serves fresh data for the initial 30 seconds. Subsequently, it serves stale data until the cache refreshes itself in the background after each request:
用例:新闻文章
¥Use case: News articles
假设有一个新闻应用,其中的文章访问频率很高,但不需要实时更新。通过将 ttl
设置为 2 小时,将 swr
设置为 5 分钟,Prisma 客户端可以快速提供缓存的文章,从而减少读者的延迟。只要文章在 ttl
范围内,用户就能快速获得响应。ttl
过期后,Prisma 客户端将继续提供过时的文章最多 5 分钟,并使用数据库中的最新新闻重新验证缓存以响应新查询。这有助于在性能和新鲜度之间保持平衡。
¥Consider a news application where articles are frequently accessed but don't require real-time updates. By setting a ttl
of 2 hours and an swr
duration of 5 minutes, Prisma Client can serve cached articles quickly, reducing latency for readers. As long as the articles are within the ttl
, users get fast responses. After the ttl
expires, Prisma Client continues to serve the stale articles for up to an additional 5 minutes, revalidating the cache with the latest news from the database in response to a new query. This helps maintain a balance between performance and freshness.
何时使其失效:如果发布了重要更新或突发新闻,缓存应立即处于 invalidated 状态,以确保读者能够及时看到最新信息。这种方法对于某些新闻可能需要覆盖正常缓存周期以确保及时性的应用特别有用。
¥When to invalidate: If a critical update or breaking news article is published, the cache should be invalidated immediately to ensure readers see the latest information without delay. This approach is especially useful for applications where certain news items may need to override the normal cache cycle for timeliness.
按需缓存失效
¥On-demand cache invalidation
如果你的应用需要实时或近实时数据,缓存失效功能可确保用户看到最新的数据,即使在使用较大的 ttl
(Time-To-Live)或 swr
(Stale-While-Revalidate)缓存策略 时也是如此。通过使缓存失效,你可以绕过延长的缓存周期,以便在需要时显示实时数据。
¥If your application requires real-time or near-real-time data, cache invalidation ensures that users see the most current data, even when using a large ttl
(Time-To-Live) or swr
(Stale-While-Revalidate) cache strategy. By invalidating your cache, you can bypass extended caching periods to show live data whenever it's needed.
你可以使用 $accelerate.invalidate
API 使缓存失效:
¥You can invalidate the cache using the $accelerate.invalidate
API:
要以编程方式使缓存的查询无效,需要付费计划。请参阅我们的 更多定价详情。
¥To programmatically invalidate cached queries, a paid plan is required. See our pricing for more details.
await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"],
},
});
你需要在 $accelerate.invalidate
API 中提供缓存标签:
¥You need to provide the cache tag in the $accelerate.invalidate
API:
try {
await prisma.$accelerate.invalidate({
tags: ["emails_with_alice"],
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === "P6003") {
console.log(
"The cache invalidation rate limit has been reached. Please try again later."
);
}
}
throw e;
}
探索 演示应用,了解 Prisma Postgres 中缓存的查询结果如何按需失效,并以清晰的时间轴显示。
¥Explore the demo app to see how cached query results in Prisma Postgres are invalidated on demand, shown in a clear timeline.
默认缓存策略
¥Default cache strategy
Prisma Postgres 默认不缓存,以避免出现意外问题。虽然缓存可以提升性能,但使用不当可能会导致错误。
¥Prisma Postgres defaults to no cache to avoid unexpected issues. While caching can improve performance, incorrect usage may lead to errors.
例如,如果在关键路径上执行查询而未指定缓存策略,则结果可能不正确,且无法给出明确的解释。此问题通常出现在无意中启用隐式缓存的情况下。
¥For instance, if a query is executed on a critical path without specifying a cache strategy, the result may be incorrect, with no clear explanation. This issue often arises when implicit caching is unintentionally left enabled.
为避免此类问题,你必须明确选择启用缓存。这可确保你知晓缓存默认未启用,从而避免潜在的错误。
¥To avoid such problems, you must explicitly opt-in to caching. This ensures you are aware that caching is not enabled by default, preventing potential errors.
当未指定缓存策略或发生缓存未命中时,缓存层会通过数据库区域附近的连接池实例将所有查询路由到数据库。
¥When no cache strategy is specified or during a cache miss, the cache layer routes all queries to the database through a connection pool instance near the database region.