diff --git a/grafana/postgres/v12/4-query-performance-analysis.json b/grafana/postgres/v12/4-query-performance-analysis.json new file mode 100644 index 0000000000..68ddfda6bd --- /dev/null +++ b/grafana/postgres/v12/4-query-performance-analysis.json @@ -0,0 +1,1318 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Enhanced PostgreSQL statement analysis dashboard with comprehensive table view and visual analytics", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 42, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "panels": [], + "title": "Comprehensive Query Analysis Table (pg_stat_statements)", + "type": "row" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "description": "Comprehensive query performance analysis from pg_stat_statements.\n\n**Column Guide:**\n- **Query ID** - Internal PostgreSQL query identifier (click to drill down)\n- **Total Runtime** - Total cumulative execution time\n- **Avg Runtime** - Average execution time per call\n- **Plan Time** - Total time spent planning queries\n- **Avg Plan Time** - Average planning time per call\n- **Calls** - Number of times executed\n- **Rows** - Total rows retrieved/affected\n- **Avg Rows** - Average rows per execution\n- **Shared Hit (MB)** - Buffer cache hits - data found in memory (higher is better)\n- **Shared Read (MB)** - Data read from disk into shared buffers (cache misses)\n- **Shared Written (MB)** - Data written from shared buffers to disk\n- **Temp Read (MB)** - Data read from temporary files (indicates memory pressure)\n- **Temp Written (MB)** - Data written to temporary files during large operations\n- **IO Time** - Time spent on disk I/O operations (requires track_io_timing)\n- **% DB Total** - Percentage of total database execution time\n- **Users** - Database roles that executed this query\n- **Query** - Normalized SQL text with constants replaced by placeholders", + "fieldConfig": { + "defaults": { + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "queryid" + }, + "properties": [ + { + "id": "displayName", + "value": "Query ID" + }, + { + "id": "unit", + "value": "string" + }, + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Opens 'Single query details' dashboard for that queryid", + "url": "/d/single-query-details?orgId=1&var-dbname=${dbname}&var-queryid=${__value.raw}&from=${__from}&to=${__to}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Total Runtime (ms)" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Avg Runtime (ms)" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Plan Time (ms)" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Avg Plan Time (ms)" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Calls" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 0 + }, + { + "id": "custom.width", + "value": 76 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Rows" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 0 + }, + { + "id": "custom.width", + "value": 73 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Avg Rows" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 1 + }, + { + "id": "custom.width", + "value": 86 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Shared Hit (MB)" + }, + "properties": [ + { + "id": "unit", + "value": "decmbytes" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Shared Read (MB)" + }, + "properties": [ + { + "id": "unit", + "value": "decmbytes" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Shared Written (MB)" + }, + "properties": [ + { + "id": "unit", + "value": "decmbytes" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Temp Read (MB)" + }, + "properties": [ + { + "id": "unit", + "value": "decmbytes" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Temp Written (MB)" + }, + "properties": [ + { + "id": "unit", + "value": "decmbytes" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "IO Time (ms)" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "decimals", + "value": 0 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "% DB Total" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Query ID" + }, + "properties": [ + { + "id": "custom.width", + "value": 229 + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "table", + "rawQuery": true, + "rawSql": "-- Enhanced comprehensive query analysis (Fast mode)\nWITH query_stats AS (\n select\n tag_data->>'queryid' as queryid,\n max((data->>'total_time')::numeric) - min((data->>'total_time')::numeric) as total_runtime,\n (max((data->>'total_time')::numeric) - min((data->>'total_time')::numeric)) / nullif(max((data->>'calls')::int8) - min((data->>'calls')::int8), 0) as avg_runtime,\n max((data->>'total_plan_time')::numeric) - min((data->>'total_plan_time')::numeric) as plan_time,\n (max((data->>'total_plan_time')::numeric) - min((data->>'total_plan_time')::numeric)) / nullif(max((data->>'calls')::int8) - min((data->>'calls')::int8), 0) as avg_plan_time,\n max((data->>'calls')::int8) - min((data->>'calls')::int8) as calls,\n max((data->>'rows')::int8) - min((data->>'rows')::int8) as rows,\n (max((data->>'rows')::int8) - min((data->>'rows')::int8))::numeric / nullif(max((data->>'calls')::int8) - min((data->>'calls')::int8), 0) as avg_rows,\n (max((data->>'shared_blks_hit')::int8) - min((data->>'shared_blks_hit')::int8)) * 8192 / 1024.0 / 1024.0 as shared_hit_mb,\n (max((data->>'shared_blks_read')::int8) - min((data->>'shared_blks_read')::int8)) * 8192 / 1024.0 / 1024.0 as shared_read_mb,\n (max((data->>'shared_blks_written')::int8) - min((data->>'shared_blks_written')::int8)) * 8192 / 1024.0 / 1024.0 as shared_written_mb,\n (max((data->>'temp_blks_read')::int8) - min((data->>'temp_blks_read')::int8)) * 8192 / 1024.0 / 1024.0 as temp_read_mb,\n (max((data->>'temp_blks_written')::int8) - min((data->>'temp_blks_written')::int8)) * 8192 / 1024.0 / 1024.0 as temp_written_mb,\n (max((data->>'blk_read_time')::numeric) - min((data->>'blk_read_time')::numeric)) + \n (max((data->>'blk_write_time')::numeric) - min((data->>'blk_write_time')::numeric)) as io_time,\n case when length(tag_data->>'query') > 150 then (tag_data->>'query')::varchar(150) || '...' else tag_data->>'query' end as query\n from stat_statements\n where dbname = '$dbname'\n and $__timeFilter(time)\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid', tag_data->>'query'\n having max((data->>'calls')::int8) - min((data->>'calls')::int8) > 0\n),\nwith_percentages AS (\n select \n *,\n 100 * total_runtime / nullif((select sum(total_runtime) from query_stats), 0) as pct_db_total\n from query_stats\n)\nselect\n queryid,\n total_runtime::int8 as \"Total Runtime (ms)\",\n avg_runtime::numeric(10,2) as \"Avg Runtime (ms)\",\n plan_time::int8 as \"Plan Time (ms)\",\n avg_plan_time::numeric(10,2) as \"Avg Plan Time (ms)\",\n calls as \"Calls\",\n rows as \"Rows\",\n avg_rows::numeric(10,1) as \"Avg Rows\",\n shared_hit_mb::numeric(10,1) as \"Shared Hit (MB)\",\n shared_read_mb::numeric(10,1) as \"Shared Read (MB)\",\n shared_written_mb::numeric(10,1) as \"Shared Written (MB)\",\n temp_read_mb::numeric(10,1) as \"Temp Read (MB)\",\n temp_written_mb::numeric(10,1) as \"Temp Written (MB)\",\n io_time::numeric(10,1) as \"IO Time (ms)\",\n pct_db_total::numeric(5,1) as \"% DB Total\",\n (select data->>'users' from stat_statements where $__timeFilter(time) and dbname = '$dbname' and tag_data->>'queryid' = with_percentages.queryid order by time desc limit 1) as \"Users\",\n query as \"Query\"\nfrom with_percentages\norder by total_runtime desc nulls last\nlimit $top", + "refId": "A" + } + ], + "title": "Enhanced Query Performance Analysis Table", + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 3, + "panels": [], + "title": "Top $top queries visual analysis (pg_stat_statements)", + "type": "row" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 4, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by calls over time\nSELECT\n $__timeGroup(time, $agg_interval),\n max((data->>'calls')::int8) - min((data->>'calls')::int8) as calls,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'calls')::int8) - min((data->>'calls')::int8) > 0\n order by max((data->>'calls')::int8) - min((data->>'calls')::int8) desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by calls over time", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 22 + }, + "id": 5, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by total execution time over time\nSELECT\n $__timeGroup(time, $agg_interval),\n max((data->>'total_time')::numeric) - min((data->>'total_time')::numeric) as total_time,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'total_time')::numeric) - min((data->>'total_time')::numeric) > 0\n order by max((data->>'total_time')::numeric) - min((data->>'total_time')::numeric) desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by execution time", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 22 + }, + "id": 6, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "desc" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by rows over time\nSELECT\n $__timeGroup(time, $agg_interval),\n max((data->>'rows')::int8) - min((data->>'rows')::int8) as rows,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'rows')::int8) - min((data->>'rows')::int8) > 0\n order by max((data->>'rows')::int8) - min((data->>'rows')::int8) desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by rows", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 30 + }, + "id": 7, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by shared blocks hit over time\nSELECT\n $__timeGroup(time, $agg_interval),\n (max((data->>'shared_blks_hit')::int8) - min((data->>'shared_blks_hit')::int8)) * 8192 / 1024.0 / 1024.0 as shared_hit_mb,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'shared_blks_hit')::int8) - min((data->>'shared_blks_hit')::int8) > 0\n order by (max((data->>'shared_blks_hit')::int8) - min((data->>'shared_blks_hit')::int8)) * 8192 / 1024.0 / 1024.0 desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by shared_blks_hit (in MB)", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 30 + }, + "id": 8, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "desc" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by shared blocks read over time\nSELECT\n $__timeGroup(time, $agg_interval),\n (max((data->>'shared_blks_read')::int8) - min((data->>'shared_blks_read')::int8)) * 8192 / 1024.0 / 1024.0 as shared_read_mb,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'shared_blks_read')::int8) - min((data->>'shared_blks_read')::int8) > 0\n order by (max((data->>'shared_blks_read')::int8) - min((data->>'shared_blks_read')::int8)) * 8192 / 1024.0 / 1024.0 desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by shared_blks_read (in MB)", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 9, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by temp blocks read over time\nSELECT\n $__timeGroup(time, $agg_interval),\n (max((data->>'temp_blks_read')::int8) - min((data->>'temp_blks_read')::int8)) * 8192 / 1024.0 / 1024.0 as temp_read_mb,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'temp_blks_read')::int8) - min((data->>'temp_blks_read')::int8) > 0\n order by (max((data->>'temp_blks_read')::int8) - min((data->>'temp_blks_read')::int8)) * 8192 / 1024.0 / 1024.0 desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by temp bytes read (in MB)", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 38 + }, + "id": 10, + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "desc" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "format": "time_series", + "rawQuery": true, + "rawSql": "-- Top queries by temp blocks written over time\nSELECT\n $__timeGroup(time, $agg_interval),\n (max((data->>'temp_blks_written')::int8) - min((data->>'temp_blks_written')::int8)) * 8192 / 1024.0 / 1024.0 as temp_written_mb,\n tag_data->>'queryid' as queryid\nFROM\n stat_statements\nWHERE\n $__timeFilter(time)\n AND dbname = '$dbname'\n AND tag_data->>'query' ~* '$query_filter_regex'\n AND tag_data->>'queryid' IN (\n select tag_data->>'queryid'\n from stat_statements\n where $__timeFilter(time) and dbname = '$dbname'\n and tag_data->>'query' ~* '$query_filter_regex'\n group by tag_data->>'queryid'\n having max((data->>'temp_blks_written')::int8) - min((data->>'temp_blks_written')::int8) > 0\n order by (max((data->>'temp_blks_written')::int8) - min((data->>'temp_blks_written')::int8)) * 8192 / 1024.0 / 1024.0 desc\n limit $top\n )\nGROUP BY 1, 3\nORDER BY 1", + "refId": "A" + } + ], + "title": "Top $top statements by temp bytes written (in MB)", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 46 + }, + "id": 12, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "## Brought to you by\n\n\n \"Cybertec\n", + "mode": "markdown" + }, + "pluginVersion": "12.1.0", + "title": "", + "transparent": true, + "type": "text" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 41, + "tags": [ + "pgwatch" + ], + "templating": { + "list": [ + { + "current": { + "text": "demo", + "value": "demo" + }, + "datasource": { + "type": "grafana-postgresql-datasource", + "uid": "pgwatch-metrics" + }, + "definition": "", + "includeAll": false, + "label": "Monitored Source", + "name": "dbname", + "options": [], + "query": "SELECT DISTINCT dbname FROM admin.all_distinct_dbname_metrics WHERE metric = 'stat_statements' ORDER BY 1;", + "refresh": 1, + "regex": "", + "type": "query" + }, + { + "current": { + "text": "20", + "value": "20" + }, + "description": "Limit output to top N entries", + "includeAll": false, + "label": "Top N", + "name": "top", + "options": [ + { + "selected": false, + "text": "5", + "value": "5" + }, + { + "selected": false, + "text": "10", + "value": "10" + }, + { + "selected": false, + "text": "15", + "value": "15" + }, + { + "selected": true, + "text": "20", + "value": "20" + }, + { + "selected": false, + "text": "30", + "value": "30" + }, + { + "selected": false, + "text": "50", + "value": "50" + } + ], + "query": "5,10,15,20,30,50", + "type": "custom" + }, + { + "current": { + "text": ".*", + "value": ".*" + }, + "description": "Custom regex filter for queries. Examples: '.*' (all queries), '^(?!.*pgwatch_generated)' (exclude pgwatch_generated), '(SELECT|INSERT)' (include only SELECT/INSERT), '^(?!.*(SELECT|INSERT))' (exclude SELECT/INSERT), 'UPDATE.*^(?!.*WHERE)' (dangerous UPDATEs without WHERE - security risk).", + "includeAll": false, + "label": "Filter RegEx", + "name": "query_filter_regex", + "options": [ + { + "selected": false, + "text": "^(?!.*pgwatch_generated)", + "value": "^(?!.*pgwatch_generated)" + }, + { + "selected": true, + "text": ".*", + "value": ".*" + }, + { + "selected": false, + "text": "^(?!.*SELECT)", + "value": "^(?!.*SELECT)" + }, + { + "selected": false, + "text": "(UPDATE|DELETE|INSERT)", + "value": "(UPDATE|DELETE|INSERT)" + }, + { + "selected": false, + "text": "UPDATE.*^(?!.*WHERE)", + "value": "UPDATE.*^(?!.*WHERE)" + } + ], + "query": "^(?!.*pgwatch_generated),.*,^(?!.*SELECT),(UPDATE|DELETE|INSERT),UPDATE.*^(?!.*WHERE)", + "type": "custom" + }, + { + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "5m", + "value": "5m" + }, + "label": "Aggregate Interval", + "name": "agg_interval", + "options": [ + { + "selected": true, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": false, + "text": "15m", + "value": "15m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "12h", + "value": "12h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + } + ], + "query": "5m,10m,15m,30m,1h,6h,12h,1d", + "refresh": 2, + "type": "interval" + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "4. Query Performance Analysis", + "uid": "query-performance-analysis", + "version": 49 +} \ No newline at end of file diff --git a/grafana/postgres/v12/stat-activity-realtime.json b/grafana/postgres/v12/stat-activity-realtime.json deleted file mode 100644 index 506a583ee7..0000000000 --- a/grafana/postgres/v12/stat-activity-realtime.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": 24, - "links": [], - "panels": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "pgwatch-metrics" - }, - "description": "Top 25 longest running queries from pg_stat_activity. Query texts are compacted", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "pid" - }, - "properties": [ - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.align" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)" - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 60 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 300 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "waiting" - }, - "properties": [ - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.align" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)" - }, - { - "color": "#C4162A", - "value": 1 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 2 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "blocking_pids" - }, - "properties": [ - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - } - ] - }, - "gridPos": { - "h": 24, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.0.0", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "pgwatch-metrics" - }, - "format": "table", - "group": [], - "metricColumn": "none", - "rawQuery": true, - "rawSql": "SELECT\n tag_data->>'pid' AS pid,\n data->>'user' AS user,\n data->>'appname' AS appname,\n data->>'ip' AS ip,\n (data->>'duration_s')::int AS duration,\n data->>'waiting' AS waiting,\n coalesce(data->>'blocking_pids', '') AS blocking_pids,\n data->>'query' AS query\nFROM\n stat_activity_realtime\nWHERE\n dbname = '$dbname'\n AND time = (SELECT max(time) FROM stat_activity_realtime WHERE dbname = '$dbname' AND $__timeFilter(time))\n AND (data->>'duration_s')::int > $min_duration_s\nORDER BY\n duration DESC\nLIMIT 25\n\n\n\n\n\n\n\n\n\n\n\n\n", - "refId": "A", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "column" - } - ] - ], - "timeColumn": "time", - "where": [ - { - "name": "$__timeFilter", - "params": [], - "type": "macro" - } - ] - } - ], - "title": "Stat Activity", - "transformations": [ - { - "id": "merge", - "options": { - "reducers": [] - } - } - ], - "type": "table" - } - ], - "preload": false, - "refresh": "5s", - "schemaVersion": 41, - "tags": [ - "pgwatch" - ], - "templating": { - "list": [ - { - "current": { - "text": "", - "value": "" - }, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "pgwatch-metrics" - }, - "definition": "SELECT DISTINCT dbname FROM admin.all_distinct_dbname_metrics WHERE metric = 'stat_activity_realtime' ORDER BY 1;", - "includeAll": false, - "name": "dbname", - "options": [], - "query": "SELECT DISTINCT dbname FROM admin.all_distinct_dbname_metrics WHERE metric = 'stat_activity_realtime' ORDER BY 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "1", - "value": "1" - }, - "name": "min_duration_s", - "options": [ - { - "selected": true, - "text": "1", - "value": "1" - } - ], - "query": "1", - "type": "textbox" - } - ] - }, - "time": { - "from": "now-5m", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m" - ] - }, - "timezone": "", - "title": "Stat Activity Realtime", - "uid": "stat-activity-realtime", - "version": 11 -} \ No newline at end of file diff --git a/grafana/postgres/v12/stat-activity.json b/grafana/postgres/v12/stat-activity.json deleted file mode 100644 index 3fddf8f4b5..0000000000 --- a/grafana/postgres/v12/stat-activity.json +++ /dev/null @@ -1,300 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": 32, - "links": [], - "panels": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "pgwatch-metrics" - }, - "description": "Top 25 longest running queries from pg_stat_activity. Query texts are compacted", - "fieldConfig": { - "defaults": { - "custom": { - "align": "auto", - "cellOptions": { - "type": "auto" - }, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "pid" - }, - "properties": [ - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - }, - { - "id": "decimals", - "value": 1 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.align" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)" - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 60 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 300 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "waiting" - }, - "properties": [ - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.cellOptions", - "value": { - "type": "color-text" - } - }, - { - "id": "custom.align" - }, - { - "id": "thresholds", - "value": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)" - }, - { - "color": "#C4162A", - "value": 1 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 2 - } - ] - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "blocking_pids" - }, - "properties": [ - { - "id": "unit", - "value": "short" - }, - { - "id": "decimals", - "value": 2 - }, - { - "id": "custom.align" - } - ] - } - ] - }, - "gridPos": { - "h": 24, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 2, - "options": { - "cellHeight": "sm", - "footer": { - "countRows": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true - }, - "pluginVersion": "12.0.0", - "targets": [ - { - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "pgwatch-metrics" - }, - "format": "table", - "group": [], - "metricColumn": "none", - "rawQuery": true, - "rawSql": "SELECT\n tag_data->>'pid' AS pid,\n data->>'user' AS user,\n data->>'appname' AS appname,\n data->>'ip' AS ip,\n (data->>'duration_s')::int AS duration,\n data->>'waiting' AS waiting,\n coalesce(data->>'blocking_pids', '') AS blocking_pids,\n data->>'query' AS query\nFROM\n stat_activity_realtime\nWHERE\n dbname = '$dbname'\n AND time = (SELECT max(time) FROM stat_activity_realtime WHERE dbname = '$dbname' AND $__timeFilter(time))\n AND (data->>'duration_s')::int > $min_duration_s\nORDER BY\n duration DESC\nLIMIT 25\n\n\n\n\n\n\n\n\n\n\n\n\n", - "refId": "A", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "column" - } - ] - ], - "timeColumn": "time", - "where": [ - { - "name": "$__timeFilter", - "params": [], - "type": "macro" - } - ] - } - ], - "title": "Stat Activity", - "type": "table" - } - ], - "preload": false, - "refresh": "5s", - "schemaVersion": 41, - "tags": [ - "pgwatch" - ], - "templating": { - "list": [ - { - "current": { - "text": "", - "value": "" - }, - "datasource": { - "type": "grafana-postgresql-datasource", - "uid": "pgwatch-metrics" - }, - "definition": "SELECT DISTINCT dbname FROM admin.all_distinct_dbname_metrics WHERE metric = 'stat_activity_realtime' ORDER BY 1;", - "includeAll": false, - "name": "dbname", - "options": [], - "query": "SELECT DISTINCT dbname FROM admin.all_distinct_dbname_metrics WHERE metric = 'stat_activity_realtime' ORDER BY 1;", - "refresh": 1, - "regex": "", - "type": "query" - }, - { - "current": { - "text": "1", - "value": "1" - }, - "name": "min_duration_s", - "options": [ - { - "selected": true, - "text": "1", - "value": "1" - } - ], - "query": "1", - "type": "textbox" - } - ] - }, - "time": { - "from": "now-5m", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m" - ] - }, - "timezone": "", - "title": "Stat Activity", - "uid": "stat-activity", - "version": 11 -} \ No newline at end of file