diff --git a/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx b/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx index 0416318a293..ca32d0806c5 100644 --- a/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx +++ b/apps/studio/components/interfaces/QueryInsights/QueryInsights.tsx @@ -50,12 +50,12 @@ export const QueryInsights = () => { const { data: databases } = useReadReplicasQuery({ projectRef: ref }) const [selectedMetric, setSelectedMetric] = useState('query_latency') - const [selectedTimeRange, setSelectedTimeRange] = useState('24h') + const [selectedTimeRange, setSelectedTimeRange] = useState('1d') const [selectedQuery, setSelectedQuery] = useState(null) const [timeRange, setTimeRange] = useState({ period_start: { date: dayjs().subtract(24, 'hour').format('YYYY-MM-DD HH:mm:ssZ'), - time_period: '24h', + time_period: '1d', }, period_end: { date: dayjs().format('YYYY-MM-DD HH:mm:ssZ'), @@ -81,11 +81,23 @@ export const QueryInsights = () => { useEffect(() => { // Update the time range when selectedTimeRange changes switch (selectedTimeRange) { - case '24h': + case '3h': + setTimeRange({ + period_start: { + date: dayjs().subtract(3, 'hour').format('YYYY-MM-DD HH:mm:ssZ'), + time_period: '3h', + }, + period_end: { + date: dayjs().format('YYYY-MM-DD HH:mm:ssZ'), + time_period: 'now', + }, + }) + break + case '1d': setTimeRange({ period_start: { date: dayjs().subtract(24, 'hour').format('YYYY-MM-DD HH:mm:ssZ'), - time_period: '24h', + time_period: '1d', }, period_end: { date: dayjs().format('YYYY-MM-DD HH:mm:ssZ'), @@ -133,12 +145,48 @@ export const QueryInsights = () => { value={selectedTimeRange} loading={isLoadingMetrics} onChange={({ period_start, period_end, interval }) => { - setSelectedTimeRange(period_start.time_period) - setTimeRange({ period_start, period_end }) + // If selecting the same time range again, force a refresh by setting with a new object + if (period_start.time_period === selectedTimeRange) { + const newTimeRange = { + period_start: { + date: + period_start.time_period === '1d' + ? dayjs().subtract(24, 'hour').format('YYYY-MM-DD HH:mm:ssZ') + : period_start.time_period === '3h' + ? dayjs().subtract(3, 'hour').format('YYYY-MM-DD HH:mm:ssZ') + : period_start.time_period === '7d' + ? dayjs().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ssZ') + : period_start.time_period === '30d' + ? dayjs().subtract(30, 'day').format('YYYY-MM-DD HH:mm:ssZ') + : period_start.date, + time_period: period_start.time_period, + }, + period_end: { + date: dayjs().format('YYYY-MM-DD HH:mm:ssZ'), + time_period: 'now', + }, + } + + // Reset state to force a refresh + setTimeRange(newTimeRange) + + // Temporarily set to a different value and then back + setSelectedTimeRange('__refreshing__') + setTimeout(() => setSelectedTimeRange(period_start.time_period), 10) + } else { + // Normal update for changing to a different time period + setSelectedTimeRange(period_start.time_period) + setTimeRange({ period_start, period_end }) + } }} options={[ { - key: '24h', + key: '3h', + label: 'Last 3 hours', + interval: '30m', + }, + { + key: '1d', label: 'Last 24 hours', interval: '1h', }, diff --git a/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx b/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx index 3b9028c8dcb..b64e2338cdb 100644 --- a/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx +++ b/apps/studio/components/interfaces/QueryInsights/components/QueryList.tsx @@ -190,6 +190,16 @@ export const QueryList = ({ queries, isLoading, onQuerySelect, selectedQuery }: ), }, + { + key: 'application_name', + name: 'Application', + resizable: true, + minWidth: 120, + headerCellClass: '', + renderCell: (props) => ( +
{props.row.application_name || 'Unknown'}
+ ), + }, // { // key: 'database', // name: 'Database', diff --git a/apps/studio/data/query-insights/query-insights-query.ts b/apps/studio/data/query-insights/query-insights-query.ts index c9e639a05b2..8c5e64a7841 100644 --- a/apps/studio/data/query-insights/query-insights-query.ts +++ b/apps/studio/data/query-insights/query-insights-query.ts @@ -33,6 +33,7 @@ export type QueryInsightsQuery = { database: string timestamp: string cmd_type_text: string + application_name: string } export type QueryInsightsMetrics = { @@ -141,11 +142,13 @@ const getQueriesSql = (startTime: string, endTime: string) => /* SQL */ ` SUM(total_exec_time) / NULLIF(SUM(calls), 0) as mean_exec_time, STRING_AGG(DISTINCT datname, ', ') as database, MAX(bucket_start_time) as timestamp, - MAX(get_cmd_type(cmd_type)) as cmd_type_text + MAX(get_cmd_type(cmd_type)) as cmd_type_text, + STRING_AGG(DISTINCT COALESCE(application_name, 'Unknown'), ', ') as application_name FROM pg_stat_monitor WHERE bucket_start_time >= '${startTime}' AND bucket_start_time <= '${endTime}' AND bucket_done = true + AND cmd_type IN (1, 2, 3, 4) -- 1=SELECT, 2=INSERT, 3=UPDATE, 4=DELETE GROUP BY queryid ORDER BY mean_exec_time DESC LIMIT 100