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)
+ })
+}
@@ -260,6 +269,14 @@ function averageIO(node: Node) {
"
>
IO:
+
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 {