diff --git a/app/[query]/clickhouse-queries.ts b/app/[query]/clickhouse-queries.ts index 80a15c9b..52aa5d34 100644 --- a/app/[query]/clickhouse-queries.ts +++ b/app/[query]/clickhouse-queries.ts @@ -18,6 +18,7 @@ import { expensiveQueriesConfig } from './queries/expensive-queries' import { expensiveQueriesByMemoryConfig } from './queries/expensive-queries-by-memory' import { failedQueriesConfig } from './queries/failed-queries' import { historyQueriesConfig } from './queries/history-queries' +import { queryCacheConfig } from './queries/query-cache' import { runningQueriesConfig } from './queries/running-queries' import { detachedPartsConfig } from './tables/detached-parts' import { distributedDdlQueueConfig } from './tables/distributed-ddl-queue' @@ -36,6 +37,7 @@ export const queries: Array = [ detachedPartsConfig, // Queries + queryCacheConfig, runningQueriesConfig, historyQueriesConfig, failedQueriesConfig, diff --git a/app/[query]/queries/query-cache.ts b/app/[query]/queries/query-cache.ts new file mode 100644 index 00000000..6a39ec2a --- /dev/null +++ b/app/[query]/queries/query-cache.ts @@ -0,0 +1,42 @@ +import { ColumnFormat } from '@/lib/types/column-format' +import { type QueryConfig } from '@/lib/types/query-config' + +export const queryCacheConfig: QueryConfig = { + name: 'query-cache', + sql: ` + SELECT + query, + result_size, + formatReadableSize(result_size) AS readable_result_size, + round(100 * result_size / max(result_size) OVER ()) AS pct_result_size, + stale, + shared, + compressed, + expires_at, + (now() - expires_at) AS expires_in, + key_hash + FROM system.query_cache + ORDER BY expires_at DESC + LIMIT 1000 + `, + columns: [ + 'query', + 'readable_result_size', + 'stale', + 'shared', + 'compressed', + 'expires_at', + 'expires_in', + 'key_hash', + ], + columnFormats: { + query: ColumnFormat.CodeToggle, + readable_result_size: ColumnFormat.BackgroundBar, + stale: ColumnFormat.Boolean, + shared: ColumnFormat.Boolean, + compressed: ColumnFormat.Boolean, + expires_in: ColumnFormat.Duration, + }, + + relatedCharts: [['query-cache', {}]], +} diff --git a/components/charts/query-cache.tsx b/components/charts/query-cache.tsx new file mode 100644 index 00000000..52fc62a9 --- /dev/null +++ b/components/charts/query-cache.tsx @@ -0,0 +1,43 @@ +import { ChartCard } from '@/components/chart-card' +import { type ChartProps } from '@/components/charts/chart-props' +import { CardMetric } from '@/components/tremor/card-metric' +import { fetchData } from '@/lib/clickhouse' + +export async function ChartQueryCache({ + title = 'Query Cache', + className, +}: ChartProps & { name?: string }) { + const query = ` + SELECT + sumIf(result_size, stale = 0) AS total_result_size, + sumIf(result_size, stale = 1) AS total_staled_result_size, + formatReadableSize(total_result_size) AS readable_total_result_size, + formatReadableSize(total_staled_result_size) AS readable_total_staled_result_size + FROM system.query_cache + ` + const { data } = await fetchData< + { + total_result_size: number + total_staled_result_size: number + readable_total_result_size: string + readable_total_staled_result_size: string + }[] + >({ query }) + const first = data?.[0] + + if (!data || !first) return null + + return ( + + + + ) +} + +export default ChartQueryCache diff --git a/menu.ts b/menu.ts index 16da6bc9..5c417777 100644 --- a/menu.ts +++ b/menu.ts @@ -23,6 +23,7 @@ import { QUERY_COMMENT } from '@/lib/clickhouse' import { CircleDollarSignIcon, CombineIcon, + DatabaseZapIcon, FilePlus2Icon, HardDriveIcon, RollerCoasterIcon, @@ -147,6 +148,12 @@ export const menuItemsConfig: MenuItem[] = [ description: 'Shows the execution plan of a statement', icon: InfoCircledIcon, }, + { + title: 'Query Cache', + href: '/query-cache', + description: 'Query cache usage', + icon: DatabaseZapIcon, + }, ], }, {