Introduce getCachedAdminCount to cache un-filtered table count(*) queries in Redis for admin lists (starting with UsersPage), avoiding heavy full table scans on every request while keeping exact counts for search/filtered queries.
27 lines
904 B
TypeScript
27 lines
904 B
TypeScript
import { count, type SQL } from "drizzle-orm";
|
|
import type { MySqlTable } from "drizzle-orm/mysql-core";
|
|
import { db } from "@/lib/db";
|
|
import { redisCache } from "@/lib/redis-cache";
|
|
|
|
/**
|
|
* Caches admin list totals when no filters are applied (no 'where' clause),
|
|
* preventing heavy COUNT(*) table scans on every request for large tables.
|
|
* Filtered queries bypass cache to ensure exact search result counts.
|
|
*/
|
|
export async function getCachedAdminCount(
|
|
table: MySqlTable,
|
|
cacheKey: string,
|
|
where?: SQL | undefined,
|
|
): Promise<number> {
|
|
// Only cache the global count (where = undefined)
|
|
if (where) {
|
|
const [row] = await db.select({ total: count() }).from(table).where(where);
|
|
return Number(row?.total ?? 0);
|
|
}
|
|
|
|
return await redisCache(`admin:count:${cacheKey}`, 60, async () => {
|
|
const [row] = await db.select({ total: count() }).from(table);
|
|
return Number(row?.total ?? 0);
|
|
});
|
|
}
|