From f0da88bf489a0eef7667a270d33dce2609cb6f14 Mon Sep 17 00:00:00 2001 From: kemal Date: Thu, 28 Aug 2025 10:04:27 +0100 Subject: [PATCH] feat: add slowness rating to table --- .../QueryInsights/QueryRowExplorer.tsx | 50 +++++++++++++++++++ .../query-insights/query-metrics-query.ts | 21 +++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/apps/studio/components/interfaces/QueryInsights/QueryRowExplorer.tsx b/apps/studio/components/interfaces/QueryInsights/QueryRowExplorer.tsx index 2445590e49d..f4a15eb7fff 100644 --- a/apps/studio/components/interfaces/QueryInsights/QueryRowExplorer.tsx +++ b/apps/studio/components/interfaces/QueryInsights/QueryRowExplorer.tsx @@ -6,6 +6,7 @@ import DataGrid, { Column, DataGridHandle, Row } from 'react-data-grid' import { useParams } from 'common' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { + Badge, Button, ResizableHandle, ResizablePanel, @@ -93,6 +94,54 @@ export const QueryRowExplorer = ({ startTime, endTime }: QueryRowExplorerProps) ) }, }, + { + key: 'slowness_rating', + name: 'Slowness Rating', + resizable: true, + minWidth: 120, + headerCellClass: 'cursor-pointer', + renderHeaderCell: () => { + return ( +
onSortChange('slowness_rating')} + > +
+

Slowness Rating

+
+ {sort?.column === 'slowness_rating' && ( + <>{sort.order === 'desc' ? : } + )} +
+ ) + }, + renderCell: (props) => { + const value = props.row?.slowness_rating + const getBadgeVariant = (rating: string) => { + switch (rating) { + case 'GREAT': + case 'ACCEPTABLE': + return 'default' + case 'NOTICEABLE': + case 'SLOW': + return 'warning' + case 'CRITICAL': + return 'destructive' + default: + return 'default' + } + } + return ( +
+ + + {value} + + +
+ ) + }, + }, { key: 'database', name: 'Database', @@ -304,6 +353,7 @@ export const QueryRowExplorer = ({ startTime, endTime }: QueryRowExplorerProps) cmd_type_text: 'SELECT', application_name: 'Test App', badness_score: 25.5, + slowness_rating: 'GREAT', error_count: 0, startup_cost_before: 0, startup_cost_after: 0, diff --git a/apps/studio/data/query-insights/query-metrics-query.ts b/apps/studio/data/query-insights/query-metrics-query.ts index 1141493d068..156b35745f9 100644 --- a/apps/studio/data/query-insights/query-metrics-query.ts +++ b/apps/studio/data/query-insights/query-metrics-query.ts @@ -38,6 +38,7 @@ export type QueryInsightsQuery = { cmd_type_text: string application_name: string badness_score: number + slowness_rating: string // index_advisor results startup_cost_before?: number startup_cost_after?: number @@ -215,7 +216,15 @@ const getQueriesSql = (startTime: string, endTime: string) => /* SQL */ ` SUM(CASE WHEN cmd_type = 3 THEN rows ELSE 0 END) + SUM(CASE WHEN cmd_type = 4 THEN rows ELSE 0 END), 1) - ) AS badness_score + ) AS badness_score, + -- Slowness rating based on mean execution time + CASE + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 100 THEN 'GREAT' + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 200 THEN 'ACCEPTABLE' + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 1000 THEN 'NOTICEABLE' + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 5000 THEN 'SLOW' + ELSE 'CRITICAL' + END AS slowness_rating FROM pg_stat_monitor WHERE bucket_start_time >= '${startTime}' AND bucket_start_time <= '${endTime}' @@ -281,7 +290,15 @@ const getQueriesWithErrorsSql = (startTime: string, endTime: string) => /* SQL * SUM(CASE WHEN cmd_type = 3 THEN rows ELSE 0 END) + SUM(CASE WHEN cmd_type = 4 THEN rows ELSE 0 END), 1) - ) AS badness_score + ) AS badness_score, + -- Slowness rating based on mean execution time + CASE + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 100 THEN 'GREAT' + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 200 THEN 'ACCEPTABLE' + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 1000 THEN 'NOTICEABLE' + WHEN SUM(total_exec_time) / NULLIF(SUM(calls), 0) < 5000 THEN 'SLOW' + ELSE 'CRITICAL' + END AS slowness_rating FROM pg_stat_monitor WHERE bucket_start_time >= '${startTime}' AND bucket_start_time <= '${endTime}'