Class: QueryGuard::Explain::QueryPlan
- Inherits:
-
Object
- Object
- QueryGuard::Explain::QueryPlan
- Defined in:
- lib/query_guard/explain/plan_signals.rb
Overview
Complete query plan and extracted signals
Instance Attribute Summary collapse
-
#execution_time_ms ⇒ Object
readonly
Returns the value of attribute execution_time_ms.
-
#planning_time_ms ⇒ Object
readonly
Returns the value of attribute planning_time_ms.
-
#root_node ⇒ Object
readonly
Returns the value of attribute root_node.
-
#triggers ⇒ Object
readonly
Returns the value of attribute triggers.
Instance Method Summary collapse
-
#initialize(explain_output) ⇒ QueryPlan
constructor
A new instance of QueryPlan.
-
#scans_for_table(table_name) ⇒ Array<PlanNode>
Find specific relation scans.
-
#sequential_scans ⇒ Array<PlanNode>
Extract all sequential scans from entire plan tree.
-
#to_h ⇒ Hash
Convert to hash for serialization.
-
#total_estimated_cost ⇒ Float
Total estimated cost of query.
-
#uses_indexes? ⇒ Boolean
Check if plan uses any indexes.
Constructor Details
#initialize(explain_output) ⇒ QueryPlan
Returns a new instance of QueryPlan.
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/query_guard/explain/plan_signals.rb', line 127 def initialize(explain_output) @raw_output = explain_output # Top-level metrics @planning_time_ms = explain_output.dig("Planning Time") || 0 @execution_time_ms = explain_output.dig("Execution Time") || 0 @triggers = explain_output.dig("Triggers") || [] # Root plan node @root_node = PlanNode.new(explain_output.dig("Plan") || {}) end |
Instance Attribute Details
#execution_time_ms ⇒ Object (readonly)
Returns the value of attribute execution_time_ms.
125 126 127 |
# File 'lib/query_guard/explain/plan_signals.rb', line 125 def execution_time_ms @execution_time_ms end |
#planning_time_ms ⇒ Object (readonly)
Returns the value of attribute planning_time_ms.
125 126 127 |
# File 'lib/query_guard/explain/plan_signals.rb', line 125 def planning_time_ms @planning_time_ms end |
#root_node ⇒ Object (readonly)
Returns the value of attribute root_node.
125 126 127 |
# File 'lib/query_guard/explain/plan_signals.rb', line 125 def root_node @root_node end |
#triggers ⇒ Object (readonly)
Returns the value of attribute triggers.
125 126 127 |
# File 'lib/query_guard/explain/plan_signals.rb', line 125 def triggers @triggers end |
Instance Method Details
#scans_for_table(table_name) ⇒ Array<PlanNode>
Find specific relation scans
150 151 152 153 |
# File 'lib/query_guard/explain/plan_signals.rb', line 150 def scans_for_table(table_name) root_node.nodes_of_type("Seq Scan") .select { |node| node.relation_name == table_name } end |
#sequential_scans ⇒ Array<PlanNode>
Extract all sequential scans from entire plan tree
142 143 144 |
# File 'lib/query_guard/explain/plan_signals.rb', line 142 def sequential_scans root_node.sequential_scans end |
#to_h ⇒ Hash
Convert to hash for serialization
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/query_guard/explain/plan_signals.rb', line 174 def to_h { planning_time_ms: planning_time_ms, execution_time_ms: execution_time_ms, total_estimated_cost: total_estimated_cost, has_sequential_scans: sequential_scans.any?, sequential_scan_count: sequential_scans.length, uses_indexes: uses_indexes?, root_node: root_node.to_h } end |
#total_estimated_cost ⇒ Float
Total estimated cost of query
167 168 169 |
# File 'lib/query_guard/explain/plan_signals.rb', line 167 def total_estimated_cost root_node.estimated_cost end |
#uses_indexes? ⇒ Boolean
Check if plan uses any indexes
158 159 160 161 162 |
# File 'lib/query_guard/explain/plan_signals.rb', line 158 def uses_indexes? root_node.nodes_of_type("Index Scan").any? || root_node.nodes_of_type("Bitmap Index Scan").any? || root_node.nodes_of_type("Index Only Scan").any? end |