Class: AwesomeExplain::SqlPlanTree
- Inherits:
-
Object
- Object
- AwesomeExplain::SqlPlanTree
- Defined in:
- app/models/awesome_explain/sql_plan_tree.rb
Instance Attribute Summary collapse
-
#actual_loops ⇒ Object
Returns the value of attribute actual_loops.
-
#actual_rows ⇒ Object
Returns the value of attribute actual_rows.
-
#actual_startup_time ⇒ Object
Returns the value of attribute actual_startup_time.
-
#actual_total_time ⇒ Object
Returns the value of attribute actual_total_time.
-
#ids ⇒ Object
Returns the value of attribute ids.
-
#plan_stats ⇒ Object
Returns the value of attribute plan_stats.
-
#plans_count ⇒ Object
Returns the value of attribute plans_count.
-
#root ⇒ Object
Returns the value of attribute root.
-
#rows ⇒ Object
Returns the value of attribute rows.
-
#seq_scan ⇒ Object
(also: #seq_scan?)
Returns the value of attribute seq_scan.
-
#seq_scans ⇒ Object
Returns the value of attribute seq_scans.
-
#startup_cost ⇒ Object
Returns the value of attribute startup_cost.
-
#total_cost ⇒ Object
Returns the value of attribute total_cost.
-
#width ⇒ Object
Returns the value of attribute width.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize ⇒ SqlPlanTree
constructor
A new instance of SqlPlanTree.
- #treeviz ⇒ Object
- #update_tree_stats(node) ⇒ Object
Constructor Details
#initialize ⇒ SqlPlanTree
Returns a new instance of SqlPlanTree.
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 19 def initialize @startup_cost = 0 @total_cost = 0 @rows = 0 @width = 0 @actual_startup_time = 0 @actual_total_time = 0 @actual_rows = 0 @actual_loops = 0 @seq_scans = 0 @plan_stats = ::AwesomeExplain::SqlPlanStats.new end |
Instance Attribute Details
#actual_loops ⇒ Object
Returns the value of attribute actual_loops.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def actual_loops @actual_loops end |
#actual_rows ⇒ Object
Returns the value of attribute actual_rows.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def actual_rows @actual_rows end |
#actual_startup_time ⇒ Object
Returns the value of attribute actual_startup_time.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def actual_startup_time @actual_startup_time end |
#actual_total_time ⇒ Object
Returns the value of attribute actual_total_time.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def actual_total_time @actual_total_time end |
#ids ⇒ Object
Returns the value of attribute ids.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def ids @ids end |
#plan_stats ⇒ Object
Returns the value of attribute plan_stats.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def plan_stats @plan_stats end |
#plans_count ⇒ Object
Returns the value of attribute plans_count.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def plans_count @plans_count end |
#root ⇒ Object
Returns the value of attribute root.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def root @root end |
#rows ⇒ Object
Returns the value of attribute rows.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def rows @rows end |
#seq_scan ⇒ Object Also known as: seq_scan?
Returns the value of attribute seq_scan.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def seq_scan @seq_scan end |
#seq_scans ⇒ Object
Returns the value of attribute seq_scans.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def seq_scans @seq_scans end |
#startup_cost ⇒ Object
Returns the value of attribute startup_cost.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def startup_cost @startup_cost end |
#total_cost ⇒ Object
Returns the value of attribute total_cost.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def total_cost @total_cost end |
#width ⇒ Object
Returns the value of attribute width.
2 3 4 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 2 def width @width end |
Class Method Details
.build(plan) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 32 def self.build(plan) tree = self.new tree.ids = (2..500).to_a # Ugh!!! root = ::AwesomeExplain::SqlPlanNode.build(plan.first.dig('Plan')) tree.root = root tree.update_tree_stats(root) root.id = 1 tree.plans_count = 1 build_recursive(plan.first.dig('Plan', 'Plans'), root, tree) tree end |
.build_recursive(data, parent, tree) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 44 def self.build_recursive(data, parent, tree) return unless data.present? if data.is_a?(Array) data.each do |plan| build_recursive(plan, parent, tree) end elsif data.is_a?(Hash) && data.dig('Plans').present? node = ::AwesomeExplain::SqlPlanNode.build(data, parent) node.id = tree.ids.shift parent.children << node tree.plans_count += 1 tree.seq_scans += 1 if node.seq_scan? tree.update_tree_stats(node) build_recursive(data.dig('Plans'), node, tree) elsif data.is_a?(Hash) && data.dig('Plans').nil? node = ::AwesomeExplain::SqlPlanNode.build(data, parent) tree.update_tree_stats(node) node.id = tree.ids.shift tree.plans_count += 1 tree.seq_scans += 1 if node.seq_scan? parent.children << node end end |
Instance Method Details
#treeviz ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 69 def treeviz return unless root.present? output = [] queue = [root] while(!queue.empty?) do node = queue.shift output << node.treeviz node.children.each do |child| queue << child end end output end |
#update_tree_stats(node) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'app/models/awesome_explain/sql_plan_tree.rb', line 84 def update_tree_stats(node) self.startup_cost += node.startup_cost self.total_cost += node.total_cost self.rows += node.rows self.width += node.width self.actual_startup_time += node.actual_startup_time self.actual_total_time += node.actual_total_time self.actual_rows += node.actual_rows self.actual_loops += node.actual_loops # Plan Stats plan_stats.total_rows_planned += node.rows plan_stats.total_rows += node.actual_rows plan_stats.total_loops += node.actual_loops plan_stats.seq_scans += 1 if node.seq_scan? relation_name = node.relation_name if relation_name if plan_stats.table_stats.dig(relation_name).nil? plan_stats.table_stats[relation_name] = { count: 0, time: 0 } end plan_stats.table_stats[relation_name][:count] += 1 plan_stats.table_stats[relation_name][:time] += node.actual_total_time end node_type = node.type if node_type if plan_stats.node_type_stats.dig(node_type).nil? plan_stats.node_type_stats[node_type] = { count: 0 } end plan_stats.node_type_stats[node_type][:count] += 1 end index_name = node.index_name if index_name if plan_stats.index_stats.dig(index_name).nil? plan_stats.index_stats[index_name] = { count: 0 } plan_stats.index_stats[index_name][:count] += 1 end end end |