From d55aaf29270678c3f161d1c3b45355b16d39365b Mon Sep 17 00:00:00 2001 From: Pierre GIRAUD Date: Thu, 10 Oct 2024 10:08:57 +0200 Subject: [PATCH] Add help message for IO Timings in parallel nodes The timings may be confusing because greater than global timing. In the case of parallel aware nodes, we show a message in node detail, plan stats and diagram tooltip. Fixes #305 --- src/components/DiagramRow.vue | 11 +++++++++++ src/components/PlanNodeDetail.vue | 12 ++++++++++++ src/components/PlanStats.vue | 17 +++++++++++++++++ src/services/help-service.ts | 1 + 4 files changed, 41 insertions(+) diff --git a/src/components/DiagramRow.vue b/src/components/DiagramRow.vue index 9ffc538d..f0e3a50c 100644 --- a/src/components/DiagramRow.vue +++ b/src/components/DiagramRow.vue @@ -11,6 +11,7 @@ import { ViewOptionsKey, } from "@/symbols" import type { IPlan, Node, ViewOptions } from "@/interfaces" +import { HelpService } from "@/services/help-service" import { EstimateDirection, BufferLocation, NodeProp, Metric } from "../enums" import LevelDivider from "@/components/LevelDivider.vue" import useNode from "@/node" @@ -40,6 +41,9 @@ if (!selectNode) { } const highlightedNodeId = inject(HighlightedNodeIdKey) +const helpService = new HelpService() +const getHelpMessage = helpService.getHelpMessage + const viewOptions = inject(ViewOptionsKey) as ViewOptions const { buffersByLocationTooltip, @@ -74,6 +78,13 @@ function getTooltipContent(node: Node): string { break case Metric.io: content += ioTooltip.value + + if ( + node[NodeProp.WORKERS_PLANNED] || + node[NodeProp.WORKERS_PLANNED_BY_GATHER] + ) { + content += `
${getHelpMessage("io timings parallel")}` + } break } if (node[NodeProp.CTE_NAME]) { diff --git a/src/components/PlanNodeDetail.vue b/src/components/PlanNodeDetail.vue index ece979f5..1fb3806b 100644 --- a/src/components/PlanNodeDetail.vue +++ b/src/components/PlanNodeDetail.vue @@ -47,6 +47,7 @@ const activeTab = ref("general") const helpService = new HelpService() const getNodeTypeDescription = helpService.getNodeTypeDescription +const getHelpMessage = helpService.getHelpMessage const { costClass, @@ -336,6 +337,17 @@ watch(activeTab, () => { Read:  {{ formattedProp("EXCLUSIVE_IO_READ_TIME") }} ~{{ formattedProp("AVERAGE_IO_READ_TIME") }} +
diff --git a/src/components/PlanStats.vue b/src/components/PlanStats.vue index 2fe4555a..b42735a0 100644 --- a/src/components/PlanStats.vue +++ b/src/components/PlanStats.vue @@ -81,6 +81,15 @@ function averageIO(node: Node) { } return r.join(", ") } + +function hasParallelChildren(node: Node) { + return node.Plans.some(function iter(a) { + if (a[NodeProp.WORKERS_PLANNED] || a[NodeProp.WORKERS_PLANNED_BY_GATHER]) { + return true + } + return Array.isArray(a.Plans) && a.Plans.some(iter) + }) +} diff --git a/src/services/help-service.ts b/src/services/help-service.ts index ddaa5f49..27d2354f 100644 --- a/src/services/help-service.ts +++ b/src/services/help-service.ts @@ -64,6 +64,7 @@ Consider modifying max_parallel_workers or max_parallel_workers_per_gather.`, "WORKERS DETAILED INFO MISSING": `Consider using EXPLAIN (ANALYZE, VERBOSE)`, "FUZZY NEEDS VERBOSE": `Information may not be accurate. Use EXPLAIN VERBOSE mode.`, "HINT TRACK_IO_TIMING": `HINT: activate track_io_timing to have details on time spent outside the PG cache.`, + "IO TIMINGS PARALLEL": "Distributed among parallel workers", } interface EaseInOutQuadOptions {