2019-01-02 04:24:12 -06:00
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
|
|
//
|
2021-01-04 04:04:45 -06:00
|
|
|
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
2019-01-02 04:24:12 -06:00
|
|
|
// This software is released under the PostgreSQL Licence
|
|
|
|
//
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
define('pgadmin.misc.explain', [
|
2019-10-10 01:35:28 -05:00
|
|
|
'sources/url_for', 'jquery', 'underscore',
|
|
|
|
'sources/pgadmin', 'backbone', 'explain_statistics',
|
2021-06-28 09:23:11 -05:00
|
|
|
'svg_downloader', 'image_mapper', 'sources/gettext', 'bootstrap',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
], function(
|
2019-10-10 01:35:28 -05:00
|
|
|
url_for, $, _, pgAdmin, Backbone, StatisticsModel,
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
svgDownloader, imageMapper, gettext
|
|
|
|
) {
|
2018-01-12 01:29:51 -06:00
|
|
|
|
|
|
|
pgAdmin = pgAdmin || window.pgAdmin || {};
|
2018-12-13 04:49:56 -06:00
|
|
|
svgDownloader = svgDownloader.default;
|
2019-10-10 01:35:28 -05:00
|
|
|
var Snap = null;
|
2018-01-12 01:29:51 -06:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
var initSnap = function(snapModule) {
|
|
|
|
Snap = snapModule;
|
|
|
|
// Snap.svg plug-in to write multitext as image name
|
2020-07-16 09:23:39 -05:00
|
|
|
Snap.plugin(function(_Snap, Element, Paper) {
|
2019-10-10 01:35:28 -05:00
|
|
|
Paper.prototype.multitext = function(x, y, txt, max_width, attributes) {
|
2020-07-16 09:23:39 -05:00
|
|
|
var svg = _Snap(),
|
2019-10-10 01:35:28 -05:00
|
|
|
abc = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
|
|
|
temp = svg.text(0, 0, abc);
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
temp.attr(attributes);
|
2016-05-15 14:37:52 -05:00
|
|
|
|
|
|
|
/*
|
2019-10-10 01:35:28 -05:00
|
|
|
* Find letter width in pixels and
|
|
|
|
* index from where the text should be broken
|
2016-05-15 14:37:52 -05:00
|
|
|
*/
|
2019-10-10 01:35:28 -05:00
|
|
|
var letter_width = temp.getBBox().width / abc.length,
|
|
|
|
word_break_index = Math.round((max_width / letter_width)) - 1;
|
|
|
|
|
|
|
|
svg.remove();
|
|
|
|
|
|
|
|
var words = txt.split(' '),
|
|
|
|
width_so_far = 0,
|
|
|
|
lines = [],
|
|
|
|
curr_line = '',
|
|
|
|
/*
|
|
|
|
* Function to divide string into multiple lines
|
|
|
|
* and store them in an array if it size crosses
|
|
|
|
* the max-width boundary.
|
|
|
|
*/
|
|
|
|
splitTextInMultiLine = function(leading, so_far, line) {
|
|
|
|
var l = line.length,
|
|
|
|
res = [];
|
|
|
|
|
|
|
|
if (l == 0)
|
|
|
|
return res;
|
|
|
|
|
|
|
|
if (so_far && (so_far + (l * letter_width) > max_width)) {
|
2018-01-12 01:29:51 -06:00
|
|
|
res.push(leading);
|
2019-10-10 01:35:28 -05:00
|
|
|
res = res.concat(splitTextInMultiLine('', 0, line));
|
|
|
|
} else if (so_far) {
|
|
|
|
res.push(leading + ' ' + line);
|
|
|
|
} else {
|
|
|
|
if (leading)
|
|
|
|
res.push(leading);
|
|
|
|
if (line.length > word_break_index + 1)
|
|
|
|
res.push(line.slice(0, word_break_index) + '-');
|
|
|
|
else
|
|
|
|
res.push(line);
|
|
|
|
res = res.concat(splitTextInMultiLine('', 0, line.slice(word_break_index)));
|
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
return res;
|
|
|
|
};
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
for (var i = 0; i < words.length; i++) {
|
|
|
|
var tmpArr = splitTextInMultiLine(
|
|
|
|
curr_line, width_so_far, words[i]
|
|
|
|
);
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
if (curr_line) {
|
|
|
|
lines = lines.slice(0, lines.length - 1);
|
|
|
|
}
|
|
|
|
lines = lines.concat(tmpArr);
|
|
|
|
curr_line = lines[lines.length - 1];
|
|
|
|
width_so_far = (curr_line.length * letter_width);
|
2018-01-12 01:29:51 -06:00
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
// Create multiple tspan for each string in array
|
|
|
|
var t = this.text(x, y, lines).attr(attributes);
|
|
|
|
t.selectAll('tspan:nth-child(n+2)').attr({
|
|
|
|
dy: '1.2em',
|
|
|
|
x: x,
|
|
|
|
});
|
|
|
|
return t;
|
|
|
|
};
|
|
|
|
});
|
|
|
|
};
|
2018-01-12 01:29:51 -06:00
|
|
|
|
|
|
|
if (pgAdmin.Explain)
|
2016-05-15 14:37:52 -05:00
|
|
|
return pgAdmin.Explain;
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
var pgExplain = pgAdmin.Explain = {
|
|
|
|
// Prefix path where images are stored
|
|
|
|
prefix: url_for('misc.index') + 'static/explain/img/',
|
|
|
|
};
|
|
|
|
|
|
|
|
// Some predefined constants used to calculate image location and its border
|
|
|
|
var pWIDTH = 100.;
|
|
|
|
var pHEIGHT = 100.;
|
|
|
|
var IMAGE_WIDTH = 50;
|
|
|
|
var IMAGE_HEIGHT = 50;
|
|
|
|
var offsetX = 200,
|
2016-05-15 14:37:52 -05:00
|
|
|
offsetY = 60;
|
2018-01-12 01:29:51 -06:00
|
|
|
var ARROW_WIDTH = 10,
|
2016-05-15 14:37:52 -05:00
|
|
|
ARROW_HEIGHT = 10,
|
|
|
|
DEFAULT_ARROW_SIZE = 2;
|
2018-01-12 01:29:51 -06:00
|
|
|
var TXT_ALIGN = 5,
|
|
|
|
TXT_SIZE = '15px';
|
|
|
|
var xMargin = 25,
|
2016-05-15 14:37:52 -05:00
|
|
|
yMargin = 25;
|
2018-01-12 01:29:51 -06:00
|
|
|
var MIN_ZOOM_FACTOR = 0.01,
|
2016-05-15 14:37:52 -05:00
|
|
|
MAX_ZOOM_FACTOR = 2,
|
|
|
|
INIT_ZOOM_FACTOR = 1;
|
2018-01-12 01:29:51 -06:00
|
|
|
var ZOOM_RATIO = 0.05;
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
var _createExplainTable = () => {
|
|
|
|
return $([
|
|
|
|
'<table class="backgrid table presentation table-bordered ',
|
|
|
|
' table-noouter-border table-hover">',
|
|
|
|
' <thead>',
|
|
|
|
' <tr>',
|
|
|
|
' <th class="renderable pga-ex-collapsible" rowspan="2"></th>',
|
|
|
|
' <th class="renderable" rowspan="2"><button disabled>',
|
|
|
|
gettext('#'), '</button></th>',
|
|
|
|
' <th class="renderable" rowspan="2"><button disabled>',
|
|
|
|
gettext('Node'), '</button></th>',
|
|
|
|
' <th class="renderable timings d-none" colspan="2"><button disabled>',
|
|
|
|
gettext('Timings'), '</button></th>',
|
|
|
|
' <th class="renderable rowsx rows plan_rows d-none" colspan="3">',
|
|
|
|
'<button disabled>', gettext('Rows') ,'</button></th>',
|
|
|
|
' <th class="renderable rows rowsx d-none" rowspan="2">',
|
|
|
|
'<button disabled>', gettext('Loops') ,'</button></th>',
|
|
|
|
/*
|
|
|
|
* TODO:: Remove the 'd-none' class, when showing the extra info row
|
|
|
|
* implemented.
|
|
|
|
*/
|
|
|
|
' <th class="renderable d-none" rowspan="2"><button disabled>',
|
|
|
|
' </tr>',
|
|
|
|
' <tr>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
|
|
|
gettext('Exclusive') , '</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
|
|
|
gettext('Inclusive') , '</button></th>',
|
|
|
|
' <th class="renderable rowsx d-none"><button disabled>',
|
|
|
|
gettext('Rows X'), '</button></th>',
|
|
|
|
' <th class="renderable rows rowsx d-none"><button disabled>',
|
|
|
|
gettext('Actual'), '</button></th>',
|
|
|
|
' <th class="renderable plan_rows rowsx d-none"><button disabled>',
|
|
|
|
gettext('Plan'), '</button></th>',
|
|
|
|
' </tr>',
|
|
|
|
' </thead>',
|
|
|
|
'</table>',
|
|
|
|
].join(''));
|
|
|
|
};
|
|
|
|
|
|
|
|
var _renderExplainTable = (_data, $_container) => {
|
|
|
|
var $explainTableData = $('<tbody></tbody>');
|
|
|
|
_.each(_data.rows, (_row) => {
|
|
|
|
var $tblRow = $(_row);
|
|
|
|
$tblRow.appendTo($explainTableData);
|
|
|
|
});
|
|
|
|
$explainTableData.appendTo($_container);
|
|
|
|
|
|
|
|
if (_data.show_timings === true) {
|
|
|
|
$_container.find('.timings').removeClass('d-none');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_data.show_rowsx === true) {
|
|
|
|
$_container.find('.rowsx').removeClass('d-none');
|
|
|
|
} else if (_data.show_rows === true) {
|
|
|
|
$_container.find('.rows').removeClass('d-none');
|
|
|
|
$_container.find('thead .rows[colspan=3]').attr('colspan', 1);
|
|
|
|
} else if (_data.show_plan_rows === true) {
|
|
|
|
$_container.find('.plan_rows').removeClass('d-none');
|
|
|
|
$_container.find('thead .rows[colspan=3]').attr('colspan', 1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var _createStatisticsTables = () => {
|
|
|
|
return $([
|
|
|
|
'<div class="row row-eq-height">',
|
|
|
|
' <div class="col-sm-6 col-xs-6">',
|
|
|
|
' <div class="col-xs-12 badge">',
|
|
|
|
gettext('Statistics per Node Type'),
|
|
|
|
' </div>',
|
|
|
|
' <table class="backgrid table presentation table-bordered ',
|
|
|
|
' table-hover" for="per_node_type">',
|
|
|
|
' <thead>',
|
|
|
|
' <tr>',
|
|
|
|
' <th class="renderable"><button disabled>',
|
|
|
|
gettext('Node type') , '</button></th>',
|
|
|
|
' <th class="renderable"><button disabled>',
|
|
|
|
gettext('Count'), '</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
|
|
|
gettext('Time spent') ,'</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
2021-03-12 00:10:17 -06:00
|
|
|
'% ', gettext('of query') ,'</button></th>',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
' </tr>',
|
|
|
|
' </thead>',
|
|
|
|
' </table>',
|
|
|
|
' </div>',
|
|
|
|
' <div class="col-sm-6 col-xs-6">',
|
|
|
|
' <div class="col-xs-12 badge">',
|
2021-03-12 00:10:17 -06:00
|
|
|
gettext('Statistics per Relation'),
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
' </div>',
|
|
|
|
' <table class="backgrid table presentation table-bordered ',
|
|
|
|
' table-hover" for="per_table">',
|
|
|
|
' <thead>',
|
|
|
|
' <tr>',
|
|
|
|
' <th class="renderable"><button disabled>',
|
2021-03-12 00:10:17 -06:00
|
|
|
gettext('Relation name') , '</button></th>',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
' <th class="renderable"><button disabled>',
|
|
|
|
gettext('Scan count'), '</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
|
|
|
gettext('Total time') ,'</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
2021-03-12 00:10:17 -06:00
|
|
|
'% ', gettext('of query') ,'</button></th>',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
' </tr>',
|
|
|
|
' <tr>',
|
|
|
|
' <th class="renderable"><button disabled>',
|
|
|
|
gettext('Node type') , '</button></th>',
|
|
|
|
' <th class="renderable"><button disabled>',
|
|
|
|
gettext('Count'), '</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
|
|
|
gettext('Sum of times') ,'</button></th>',
|
|
|
|
' <th class="renderable timings d-none"><button disabled>',
|
2021-03-12 00:10:17 -06:00
|
|
|
'% ', gettext('of relation') ,'</button></th>',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
' </tr>',
|
|
|
|
' </thead>',
|
|
|
|
' </table>',
|
|
|
|
' </div>',
|
|
|
|
'</div>',
|
|
|
|
].join(''));
|
|
|
|
};
|
|
|
|
|
|
|
|
var _statisticRowTemplate = _.template([
|
|
|
|
'<tr<% if (className) {%> class="<%=className%>"<%}%>>',
|
|
|
|
' <td class="renderable name"><%- data.name %></td>',
|
|
|
|
' <td class="renderable text-right"><%- data.count %></td>',
|
|
|
|
' <td class="renderable timings d-none text-right">',
|
|
|
|
'<%=Math.ceil10(data.sum_of_times, -3)%> ms',
|
|
|
|
'</td>',
|
|
|
|
' <td class="renderable timings d-none text-right">',
|
|
|
|
'<%=Math.ceil10(((data.sum_of_times||0)/(total_time||1)) * 100, -2)%>%',
|
|
|
|
'</td>',
|
|
|
|
'</tr>',
|
|
|
|
].join(''));
|
|
|
|
|
|
|
|
var _renderStatisticsTable = (_data, $_container) => {
|
|
|
|
var $perTableTbl = $_container.find('table[for="per_table"]'),
|
|
|
|
$perNodeTbl = $_container.find('table[for="per_node_type"]');
|
|
|
|
|
|
|
|
_.each(
|
|
|
|
_.sortBy(_.values(_data.statistics.nodes), 'name'),
|
|
|
|
(_node) => (
|
|
|
|
$perNodeTbl.append(_statisticRowTemplate({
|
|
|
|
'data': _node, 'total_time': _data.total_time,
|
|
|
|
'className': '',
|
|
|
|
}))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
_.each(
|
|
|
|
_.sortBy(_.values(_data.statistics.tables), 'name'),
|
|
|
|
(_table) => {
|
|
|
|
_table.sum_of_times = 0;
|
|
|
|
_.each(_table.nodes, (_node) => (
|
|
|
|
_table.sum_of_times += _node.sum_of_times
|
|
|
|
));
|
|
|
|
$perTableTbl.append(_statisticRowTemplate({
|
|
|
|
'data': _table, 'total_time': _data.total_time,
|
|
|
|
'className': 'table',
|
|
|
|
}));
|
|
|
|
|
|
|
|
_.each(
|
|
|
|
_.sortBy(_.values(_table.nodes), 'name'),
|
|
|
|
(_node) => {
|
|
|
|
$perTableTbl.append(_statisticRowTemplate({
|
|
|
|
'data': _node, 'total_time': _table.sum_of_times,
|
|
|
|
'className': 'node',
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
if (_data.show_timings) {
|
|
|
|
$_container.find('.timings').removeClass('d-none');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var _explainRowTemplate = _.template([
|
|
|
|
'<tr class="pga-ex-row',
|
|
|
|
'<% if (data["Plans"] && data["Plans"].length > 0) {%>',
|
|
|
|
' pga-ex-collapsible',
|
|
|
|
'<%}%>',
|
|
|
|
'<% if (data["exclusive_flag"] !== "undefined") {%>',
|
|
|
|
' pga-ex-exclusive-', '<%- data["exclusive_flag"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
'<% if (data["inclusive_flag"] !== "undefined") {%>',
|
|
|
|
' pga-ex-inclusive-', '<%- data["inclusive_flag"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
'<% if (data["rowsx_flag"] !== "undefined") {%>',
|
|
|
|
' pga-ex-rowsx-', '<%- data["rowsx_flag"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
'"',
|
|
|
|
'<% if (data["parent_node"]) {%>',
|
|
|
|
' data-parent="pga_ex_<%= data["parent_node"] %>"',
|
|
|
|
'<%}%>',
|
|
|
|
' data-ex-id="pga_ex_<%= data["level"].join("_") %>">',
|
|
|
|
' <td class="renderable pg-ex-highlighter clickable">',
|
|
|
|
' <i class="fa fa-circle invisible"></i>',
|
|
|
|
'</td>',
|
|
|
|
' <td class="renderable clickable serial text-right">',
|
|
|
|
'<%= (data["_serial"]) %>.</td>',
|
|
|
|
' <td class="renderable clickable" style="padding-left: ',
|
|
|
|
'<%= (data["level"].length) * 30%>px"',
|
|
|
|
'title="<%= tooltip_text %>"',
|
|
|
|
'>',
|
2020-08-13 01:34:00 -05:00
|
|
|
' <i class="pg-ex-subplans fa fa-long-arrow-alt-right"></i>',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
'<%= display_text %>',
|
|
|
|
'<%if (node_extra_info && node_extra_info.length > 0 ) {%>',
|
|
|
|
'<ui>',
|
|
|
|
'<% for (var node_info_idx=0; ',
|
|
|
|
' node_info_idx<node_extra_info.length;node_info_idx++) {%>',
|
|
|
|
' <li>', '<%= node_extra_info[node_info_idx] %>', '</li>',
|
|
|
|
'<% }%>',
|
|
|
|
'</ui>',
|
|
|
|
'<%}%>',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable timings d-none text-right ',
|
|
|
|
'<% if (data["exclusive_flag"] !== "undefined") {%>',
|
|
|
|
'pga-ex-exclusive-', '<%- data["exclusive_flag"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
'">',
|
|
|
|
'<% if (typeof(data["exclusive"]) !== "undefined") {%>', '<%= data["exclusive"] %> ms', '<%}%>',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable timings d-none text-right ',
|
|
|
|
'<% if (data["inclusive_flag"] !== "undefined") {%>',
|
|
|
|
'pga-ex-inclusive-', '<%- data["inclusive_flag"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
'">',
|
|
|
|
'<% if (typeof(data["inclusive"]) !== "undefined") {%>', '<%= data["inclusive"] %> ms', '<%}%>',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable rowsx d-none text-right ',
|
|
|
|
'<% if (data["rowsx_flag"] !== "undefined") {%>',
|
|
|
|
'pga-ex-rowsx-', '<%- data["rowsx_flag"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
'">',
|
|
|
|
'<% if (data["rowsx_direction"] === "positive") {%>',
|
|
|
|
'↑',
|
|
|
|
'<%} else {%>',
|
|
|
|
'↓',
|
|
|
|
'<%}%> ',
|
|
|
|
'<% if (typeof(data["rowsx"]) !== "undefined") {%>',
|
|
|
|
'<%- data["rowsx"] %>',
|
|
|
|
'<%}%> ',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable rowsx rows d-none text-right">',
|
|
|
|
'<% if (typeof(data["Actual Rows"]) !== "undefined") {%>',
|
|
|
|
'<%= data["Actual Rows"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable rowsx plan_rows d-none text-right">',
|
|
|
|
'<%= data["Plan Rows"] %>',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable rows rowsx d-none text-right">',
|
|
|
|
'<% if (typeof(data["Actual Loops"]) !== "undefined") {%>',
|
|
|
|
'<%= data["Actual Loops"] %>',
|
|
|
|
'<%}%>',
|
|
|
|
' </td>',
|
|
|
|
' <td class="renderable d-none">',
|
|
|
|
' <i class="fa fa-ellipsis-h"></i>',
|
|
|
|
' </td>',
|
|
|
|
'</tr>',
|
|
|
|
].join(''));
|
|
|
|
|
|
|
|
var _nodeExplainTableData = (_planData, _ctx) => {
|
|
|
|
let node_info,
|
|
|
|
display_text = ['<span class="pg-explain-text-name">'],
|
|
|
|
tooltip = [],
|
|
|
|
node_extra_info = [],
|
|
|
|
info = _ctx._explainTable;
|
|
|
|
|
|
|
|
// Display: <NODE>[ using <Index> ] [ on <Schema>.<Table>[ as <Alias>]]
|
|
|
|
|
|
|
|
if (/Scan/.test(_planData['Node Type'])) {
|
|
|
|
display_text.push(_planData['Node Type']);
|
|
|
|
tooltip.push(_planData['Node Type']);
|
|
|
|
} else {
|
|
|
|
display_text.push(_planData['image_text']);
|
|
|
|
tooltip.push(_planData['image_text']);
|
|
|
|
}
|
|
|
|
node_info = tooltip.join('');
|
|
|
|
display_text.push('</span>');
|
|
|
|
|
|
|
|
if (typeof(_planData['Index Name']) !== 'undefined') {
|
|
|
|
display_text.push(' using ');
|
|
|
|
tooltip.push(' using ');
|
|
|
|
display_text.push('<span class="pg-explain-text-name">');
|
|
|
|
display_text.push(_.escape(_planData['Index Name']));
|
|
|
|
tooltip.push(_planData['Index Name']);
|
|
|
|
display_text.push('</span>');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof(_planData['Relation Name']) !== 'undefined') {
|
|
|
|
display_text.push(' on ');
|
|
|
|
tooltip.push(' on ');
|
|
|
|
if (typeof(_planData['Schema']) !== 'undefined') {
|
|
|
|
display_text.push('<span class="pg-explain-text-name">');
|
|
|
|
display_text.push(_.escape(_planData['Schema']));
|
|
|
|
tooltip.push(_planData['Schema']);
|
|
|
|
display_text.push('</span>');
|
|
|
|
display_text.push('.');
|
|
|
|
tooltip.push('.');
|
|
|
|
}
|
|
|
|
display_text.push('<span class="pg-explain-text-name">');
|
|
|
|
display_text.push(_.escape(_planData['Relation Name']));
|
|
|
|
tooltip.push(_planData['Relation Name']);
|
|
|
|
display_text.push('</span>');
|
|
|
|
|
|
|
|
if (typeof(_planData['Alias']) !== 'undefined') {
|
|
|
|
display_text.push(' as ');
|
|
|
|
tooltip.push(' as ');
|
|
|
|
display_text.push('<span class="pg-explain-text-name">');
|
|
|
|
display_text.push(_.escape(_planData['Alias']));
|
2019-12-09 06:30:56 -06:00
|
|
|
tooltip.push(_.escape(_planData['Alias']));
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
display_text.push('</span>');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
typeof(_planData['Plan Rows']) !== 'undefined' &&
|
|
|
|
typeof(_planData['Plan Width']) !== 'undefined'
|
|
|
|
) {
|
|
|
|
let cost = [
|
|
|
|
' (cost=',
|
|
|
|
(typeof(_planData['Startup Cost']) !== 'undefined' ?
|
|
|
|
_planData['Startup Cost'] : ''),
|
|
|
|
'..',
|
|
|
|
(typeof(_planData['Total Cost']) !== 'undefined' ?
|
|
|
|
_planData['Total Cost'] : ''),
|
|
|
|
' rows=',
|
|
|
|
_planData['Plan Rows'],
|
|
|
|
' width=',
|
|
|
|
_planData['Plan Width'],
|
|
|
|
')',
|
|
|
|
].join('');
|
|
|
|
display_text.push(cost);
|
|
|
|
tooltip.push(cost);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
typeof(_planData['Actual Startup Time']) !== 'undefined' ||
|
|
|
|
typeof(_planData['Actual Total Time']) !== 'undefined' ||
|
|
|
|
typeof(_planData['Actual Rows']) !== 'undefined'
|
|
|
|
) {
|
|
|
|
let actual = [
|
|
|
|
' (',
|
|
|
|
(typeof(_planData['Actual Startup Time']) !== 'undefined' ?
|
|
|
|
('actual=' + _planData['Actual Startup Time']) + '..' : ''
|
|
|
|
),
|
|
|
|
(typeof(_planData['Actual Total Time']) !== 'undefined' ?
|
|
|
|
_planData['Actual Total Time'] + ' ' : ''
|
|
|
|
),
|
|
|
|
(typeof(_planData['Actual Rows']) !== 'undefined' ?
|
|
|
|
('rows=' + _planData['Actual Rows']) : ''
|
|
|
|
),
|
|
|
|
(typeof(_planData['Actual Loops']) !== 'undefined' ?
|
|
|
|
(' loops=' + _planData['Actual Loops']) : ''
|
|
|
|
),
|
|
|
|
')',
|
|
|
|
].join('');
|
|
|
|
|
|
|
|
display_text.push(actual);
|
|
|
|
tooltip.push(actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('Join Filter' in _planData) {
|
|
|
|
node_extra_info.push(
|
2020-04-20 00:49:09 -05:00
|
|
|
'<strong>' + gettext('Join Filter') + '</strong>: ' + _.escape(_planData['Join Filter'])
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('Filter' in _planData) {
|
2020-04-20 00:49:09 -05:00
|
|
|
node_extra_info.push('<strong>' + gettext('Filter') + '</strong>: ' + _.escape(_planData['Filter']));
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if ('Index Cond' in _planData) {
|
2020-04-20 00:49:09 -05:00
|
|
|
node_extra_info.push('<strong>' + gettext('Index Cond') + '</strong>: ' + _.escape(_planData['Index Cond']));
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if ('Hash Cond' in _planData) {
|
2020-04-20 00:49:09 -05:00
|
|
|
node_extra_info.push('<strong>' + gettext('Hash Cond') + '</strong>: ' + _.escape(_planData['Hash Cond']));
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if ('Rows Removed by Filter' in _planData) {
|
|
|
|
node_extra_info.push(
|
2020-04-20 00:49:09 -05:00
|
|
|
'<strong>' + gettext('Rows Removed by Filter') + '</strong>: ' +
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
_.escape(_planData['Rows Removed by Filter'])
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('Peak Memory Usage' in _planData) {
|
|
|
|
var buffer = [
|
2020-04-20 00:49:09 -05:00
|
|
|
'<strong>' + gettext('Buckets') + '</strong>:', _.escape(_planData['Hash Buckets']),
|
|
|
|
'<strong>' + gettext('Batches') + '</strong>:', _.escape(_planData['Hash Batches']),
|
|
|
|
'<strong>' + gettext('Memory Usage') + '</strong>:', _.escape(_planData['Peak Memory Usage']), 'kB',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
].join(' ');
|
|
|
|
node_extra_info.push(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('Recheck Cond' in _planData) {
|
2020-04-20 00:49:09 -05:00
|
|
|
node_extra_info.push('<strong>' + gettext('Recheck Cond') + '</strong>: ' + _planData['Recheck Cond']);
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if ('Exact Heap Blocks' in _planData) {
|
2020-04-20 00:49:09 -05:00
|
|
|
node_extra_info.push('<strong>' + gettext('Heap Blocks') + '</strong>: exact=' + _planData['Exact Heap Blocks']);
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
info.rows.push(_explainRowTemplate({
|
|
|
|
data: _planData,
|
|
|
|
display_text: display_text.join(''),
|
|
|
|
tooltip_text: tooltip.join(''),
|
|
|
|
node_extra_info: node_extra_info,
|
|
|
|
}));
|
|
|
|
|
|
|
|
if (typeof(_planData['exclusive_flag']) !== 'undefined') {
|
|
|
|
info.show_timings = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof(_planData['rowsx_flag']) !== 'undefined') {
|
|
|
|
info.show_rowsx = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof(_planData['Actual Loops']) !== 'undefined') {
|
|
|
|
info.show_rows = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof(_planData['Plan Rows']) !== 'undefined') {
|
|
|
|
info.show_plan_rows = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof(_planData['total_time']) !== 'undefined') {
|
|
|
|
info.total_time = _planData['total_time'];
|
|
|
|
}
|
|
|
|
|
|
|
|
let node;
|
|
|
|
|
|
|
|
if (typeof(_planData['Relation Name']) !== 'undefined') {
|
|
|
|
let relationName = (
|
|
|
|
typeof(_planData['Schema']) !== 'undefined' ?
|
|
|
|
(_planData['Schema'] + '.') : ''
|
|
|
|
) + _planData['Relation Name'],
|
|
|
|
table = info.statistics.tables[relationName] || {
|
|
|
|
name: relationName,
|
|
|
|
count: 0,
|
|
|
|
sum_of_times: 0,
|
|
|
|
nodes: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
node = table.nodes[node_info] || {
|
|
|
|
name: node_info,
|
|
|
|
count: 0,
|
|
|
|
sum_of_times: 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
table.count++;
|
|
|
|
table.sum_of_times += _planData['exclusive'];
|
|
|
|
node.count++;
|
|
|
|
node.sum_of_times += _planData['exclusive'];
|
|
|
|
|
|
|
|
table.nodes[node_info] = node;
|
|
|
|
info.statistics.tables[relationName] = table;
|
|
|
|
}
|
|
|
|
|
|
|
|
node = info.statistics.nodes[node_info] || {
|
|
|
|
name: node_info,
|
|
|
|
count: 0,
|
|
|
|
sum_of_times: 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
node.count++;
|
|
|
|
node.sum_of_times += _planData['exclusive'];
|
|
|
|
info.statistics.nodes[node_info] = node;
|
|
|
|
};
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Backbone model for each plan property of input JSON object
|
|
|
|
var PlanModel = Backbone.Model.extend({
|
2016-05-15 14:37:52 -05:00
|
|
|
defaults: {
|
2018-01-12 01:29:51 -06:00
|
|
|
'Plans': [],
|
|
|
|
level: [],
|
|
|
|
'image': undefined,
|
|
|
|
'image_text': undefined,
|
|
|
|
xpos: undefined,
|
|
|
|
ypos: undefined,
|
|
|
|
width: pWIDTH,
|
|
|
|
height: pHEIGHT,
|
2016-05-15 14:37:52 -05:00
|
|
|
},
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
|
|
|
|
_createSame: function() {
|
|
|
|
return new PlanModel();
|
|
|
|
},
|
|
|
|
|
|
|
|
parse: function(data, _opt) {
|
2018-01-12 01:29:51 -06:00
|
|
|
var idx = 1,
|
|
|
|
lvl = data.level = data.level || [idx],
|
|
|
|
plans = [],
|
|
|
|
node_type = data['Node Type'],
|
|
|
|
// Calculating relative xpos of current node from top node
|
|
|
|
xpos = data.xpos = data.xpos - pWIDTH,
|
|
|
|
// Calculating relative ypos of current node from top node
|
|
|
|
ypos = data.ypos,
|
|
|
|
maxChildWidth = 0;
|
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
_opt.ctx.totalNodes++;
|
|
|
|
_opt.ctx._explainTable.total_time = data['total_time'] || data['Actual Total Time'];
|
|
|
|
|
|
|
|
data['_serial'] = _opt.ctx.totalNodes;
|
2018-01-12 01:29:51 -06:00
|
|
|
data['width'] = pWIDTH;
|
|
|
|
data['height'] = pHEIGHT;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* calculating xpos, ypos, width and height if current node is a subplan
|
|
|
|
*/
|
|
|
|
if (data['Parent Relationship'] === 'SubPlan') {
|
|
|
|
data['width'] += (xMargin * 2) + (xMargin / 2);
|
|
|
|
data['height'] += (yMargin * 2);
|
|
|
|
data['ypos'] += yMargin;
|
|
|
|
xpos -= xMargin;
|
|
|
|
ypos += yMargin;
|
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-10-10 01:35:28 -05:00
|
|
|
if (node_type.startsWith('(slice'))
|
2018-01-12 01:29:51 -06:00
|
|
|
node_type = node_type.substring(0, 7);
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Get the image information for current node
|
2019-05-30 07:19:43 -05:00
|
|
|
let imageStore = imageMapper.default;
|
|
|
|
var mappedImage = (_.isFunction(imageStore[node_type]) &&
|
|
|
|
imageStore[node_type].apply(undefined, [data])) ||
|
|
|
|
imageStore[node_type] || {
|
2019-03-14 10:11:16 -05:00
|
|
|
'image': 'ex_unknown.svg',
|
|
|
|
'image_text': node_type,
|
|
|
|
};
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
data['image'] = mappedImage['image'];
|
|
|
|
data['image_text'] = mappedImage['image_text'];
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
if ('Actual Total Time' in data && 'Actual Loops' in data) {
|
|
|
|
data['inclusive'] = Math.ceil10(
|
2021-12-09 05:29:43 -06:00
|
|
|
data['Actual Total Time'], -3
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
);
|
|
|
|
data['exclusive'] = data['inclusive'];
|
|
|
|
data['inclusive_factor'] = data['inclusive'] / (
|
|
|
|
data['total_time'] || data['Actual Total Time']
|
|
|
|
);
|
|
|
|
data['inclusive_flag'] = data['inclusive_factor'] <= 0.1 ? '1' :
|
|
|
|
data['inclusive_factor'] < 0.5 ? '2' :
|
|
|
|
data['inclusive_factor'] <= 0.9 ? '3' : '4';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('Actual Rows' in data && 'Plan Rows' in data) {
|
|
|
|
if (
|
|
|
|
data['Actual Rows'] === 0 || data['Actual Rows'] > data['Plan Rows']
|
|
|
|
) {
|
|
|
|
data['rowsx'] = data['Plan Rows'] === 0 ? 0 :
|
|
|
|
(data['Actual Rows'] / data['Plan Rows']);
|
|
|
|
data['rowsx_direction'] = 'negative';
|
|
|
|
} else {
|
|
|
|
data['rowsx'] = data['Actual Rows'] === 0 ? 0 : (
|
|
|
|
data['Plan Rows'] / data['Actual Rows']
|
|
|
|
);
|
|
|
|
data['rowsx_direction'] = 'positive';
|
|
|
|
}
|
|
|
|
data['rowsx_flag'] = data['rowsx'] <= 10 ? '1' : (
|
|
|
|
data['rowsx'] <= 100 ? '2' : (data['rowsx'] <= 1000 ? '3' : '4')
|
|
|
|
);
|
2021-12-09 05:29:43 -06:00
|
|
|
data['rowsx'] = Math.ceil10(data['rowsx'] / data['loops'], -2);
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Start calculating xpos, ypos, width and height for child plans if any
|
|
|
|
if ('Plans' in data) {
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
var obj = this,
|
|
|
|
inclusive;
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
data['width'] += offsetX;
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
_.each(data['Plans'], function(p) {
|
|
|
|
var level = _.clone(lvl),
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
plan = obj._createSame();
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
level.push(idx);
|
|
|
|
plan.set(plan.parse(_.extend(
|
|
|
|
p, {
|
|
|
|
'level': level,
|
|
|
|
xpos: xpos - offsetX,
|
|
|
|
ypos: ypos,
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
total_time: data['total_time'] || data['Actual Total Time'],
|
|
|
|
parent_node: lvl.join('_'),
|
2021-12-09 05:29:43 -06:00
|
|
|
loops: data['Actual Loops']
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}), _opt));
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
if (maxChildWidth < plan.get('width')) {
|
|
|
|
maxChildWidth = plan.get('width');
|
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
if ('exclusive' in data) {
|
|
|
|
inclusive = plan.get('inclusive');
|
2021-12-09 05:29:43 -06:00
|
|
|
if (inclusive && inclusive < data['exclusive']) {
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
data['exclusive'] -= inclusive;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
var childHeight = plan.get('height');
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
if (idx !== 1) {
|
|
|
|
data['height'] = data['height'] + childHeight + offsetY;
|
|
|
|
} else if (childHeight > data['height']) {
|
|
|
|
data['height'] = childHeight;
|
|
|
|
}
|
|
|
|
ypos += childHeight + offsetY;
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
plans.push(plan);
|
|
|
|
idx++;
|
|
|
|
});
|
2021-12-09 05:29:43 -06:00
|
|
|
} else{
|
|
|
|
data['inclusive'] = Math.ceil10(data['Actual Total Time'] / data['loops'], -3)
|
|
|
|
data['exclusive'] = data['inclusive'];
|
2018-01-12 01:29:51 -06:00
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
if ('exclusive' in data) {
|
|
|
|
data['exclusive'] = Math.ceil10(data['exclusive'], -3);
|
|
|
|
data['exclusive_factor'] = (
|
|
|
|
data['exclusive'] / (data['total_time'] || data['Actual Total Time'])
|
|
|
|
);
|
|
|
|
data['exclusive_flag'] = data['exclusive_factor'] <= 0.1 ? '1' :
|
|
|
|
data['exclusive_factor'] < 0.5 ? '2' :
|
|
|
|
data['exclusive_factor'] <= 0.9 ? '3' : '4';
|
|
|
|
}
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Final Width and Height of current node
|
|
|
|
data['width'] += maxChildWidth;
|
|
|
|
data['Plans'] = plans;
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
return data;
|
2016-05-15 14:37:52 -05:00
|
|
|
},
|
|
|
|
|
2021-01-12 05:13:30 -06:00
|
|
|
getLabel: function() {
|
|
|
|
return this.get('Schema') == undefined ?
|
|
|
|
this.get('image_text') :
|
|
|
|
(this.get('Schema') + '.' + this.get('image_text'));
|
|
|
|
},
|
|
|
|
|
2016-05-15 14:37:52 -05:00
|
|
|
// Draw image, its name and its tooltip
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
draw: function(
|
|
|
|
s, xpos, ypos, pXpos, pYpos, graphContainer, toolTipContainer,
|
|
|
|
_ctx
|
|
|
|
) {
|
2018-01-12 01:29:51 -06:00
|
|
|
var g = s.g();
|
|
|
|
var currentXpos = xpos + this.get('xpos'),
|
|
|
|
currentYpos = ypos + this.get('ypos'),
|
|
|
|
isSubPlan = (this.get('Parent Relationship') === 'SubPlan');
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
var planData = this.toJSON();
|
2020-09-17 09:47:54 -05:00
|
|
|
var colorFg = getComputedStyle(document.documentElement).getPropertyValue('--color-fg');
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
|
|
|
|
_nodeExplainTableData(planData, _ctx);
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Draw the subplan rectangle
|
|
|
|
if (isSubPlan) {
|
|
|
|
g.rect(
|
|
|
|
currentXpos - this.get('width') + pWIDTH + xMargin,
|
|
|
|
currentYpos - this.get('height') + pHEIGHT + yMargin - TXT_ALIGN,
|
|
|
|
this.get('width') - xMargin,
|
|
|
|
this.get('height') + (currentYpos - yMargin),
|
|
|
|
5
|
|
|
|
).attr({
|
|
|
|
stroke: '#444444',
|
|
|
|
'strokeWidth': 1.2,
|
|
|
|
fill: 'gray',
|
|
|
|
fillOpacity: 0.2,
|
|
|
|
});
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Provide subplan name
|
|
|
|
g.text(
|
|
|
|
currentXpos + pWIDTH - (this.get('width') / 2) - xMargin,
|
|
|
|
currentYpos + pHEIGHT - (this.get('height') / 2) - yMargin,
|
|
|
|
this.get('Subplan Name')
|
|
|
|
).attr({
|
|
|
|
fontSize: TXT_SIZE,
|
|
|
|
'text-anchor': 'start',
|
|
|
|
fill: 'red',
|
|
|
|
});
|
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
this._drawImage(
|
|
|
|
s, g, pgExplain.prefix + this.get('image'), currentXpos, currentYpos,
|
|
|
|
graphContainer, toolTipContainer, _ctx
|
|
|
|
);
|
|
|
|
|
2018-12-13 04:49:56 -06:00
|
|
|
|
|
|
|
// Draw text below the node
|
2021-01-12 05:13:30 -06:00
|
|
|
var node_label = this.getLabel();
|
2018-12-13 04:49:56 -06:00
|
|
|
g.multitext(
|
|
|
|
currentXpos + (pWIDTH / 2) + TXT_ALIGN,
|
|
|
|
currentYpos + pHEIGHT - TXT_ALIGN,
|
|
|
|
node_label,
|
|
|
|
150, {
|
|
|
|
'font-size': TXT_SIZE,
|
|
|
|
'text-anchor': 'middle',
|
2020-09-17 09:47:54 -05:00
|
|
|
'fill': colorFg,
|
2018-12-13 04:49:56 -06:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
// Draw Arrow to parent only its not the first node
|
|
|
|
if (!_.isUndefined(pYpos)) {
|
|
|
|
var startx = currentXpos + pWIDTH;
|
|
|
|
var starty = currentYpos + (pHEIGHT / 2);
|
|
|
|
var endx = pXpos - ARROW_WIDTH;
|
|
|
|
var endy = pYpos + (pHEIGHT / 2);
|
|
|
|
var start_cost = this.get('Startup Cost'),
|
|
|
|
total_cost = this.get('Total Cost');
|
|
|
|
var arrow_size = DEFAULT_ARROW_SIZE;
|
|
|
|
|
|
|
|
// Calculate arrow width according to cost of a particular plan
|
|
|
|
if (start_cost != undefined && total_cost != undefined) {
|
|
|
|
arrow_size = Math.round(Math.log((start_cost + total_cost) / 2 + start_cost));
|
|
|
|
arrow_size = arrow_size < 1 ? 1 : arrow_size > 10 ? 10 : arrow_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
var arrow_view_box = [0, 0, 2 * ARROW_WIDTH, 2 * ARROW_HEIGHT];
|
|
|
|
var opts = {
|
2020-09-17 09:47:54 -05:00
|
|
|
stroke: colorFg,
|
2018-12-13 04:49:56 -06:00
|
|
|
strokeWidth: arrow_size + 2,
|
|
|
|
},
|
|
|
|
subplanOpts = {
|
2020-09-17 09:47:54 -05:00
|
|
|
stroke: colorFg,
|
2018-12-13 04:49:56 -06:00
|
|
|
strokeWidth: arrow_size + 2,
|
|
|
|
},
|
|
|
|
arrowOpts = {
|
|
|
|
viewBox: arrow_view_box.join(' '),
|
2020-09-17 09:47:54 -05:00
|
|
|
fill: colorFg,
|
2018-12-13 04:49:56 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
// Draw an arrow from current node to its parent
|
|
|
|
this.drawPolyLine(
|
|
|
|
g, startx, starty, endx, endy,
|
|
|
|
isSubPlan ? subplanOpts : opts, arrowOpts
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
var plans = this.get('Plans');
|
|
|
|
|
|
|
|
// Draw nodes for current plan's children
|
|
|
|
_.each(plans, function(p) {
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
p.draw(
|
|
|
|
s, xpos, ypos, currentXpos, currentYpos, graphContainer,
|
|
|
|
toolTipContainer, _ctx
|
|
|
|
);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
_drawImage: function(
|
|
|
|
s, g, image_url, startX, startY, graphContainer, toolTipContainer /*,
|
|
|
|
_ctx
|
|
|
|
*/
|
|
|
|
) {
|
|
|
|
this.drawImage(
|
|
|
|
g, image_url, startX, startY, graphContainer, toolTipContainer
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Required to parse and include non-default params of
|
|
|
|
* plan into backbone model
|
|
|
|
*/
|
|
|
|
toJSON: function(non_recursive) {
|
|
|
|
var res = Backbone.Model.prototype.toJSON.apply(this, arguments);
|
|
|
|
|
|
|
|
if (non_recursive) {
|
|
|
|
delete res['Plans'];
|
|
|
|
} else {
|
|
|
|
var plans = [];
|
|
|
|
_.each(res['Plans'], function(p) {
|
|
|
|
plans.push(p.toJSON());
|
|
|
|
});
|
|
|
|
res['Plans'] = plans;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
},
|
|
|
|
|
|
|
|
// Draw an arrow to parent node
|
|
|
|
drawPolyLine: function(g, startX, startY, endX, endY, opts, arrowOpts) {
|
|
|
|
// Calculate end point of first starting straight line (startx1, starty1)
|
|
|
|
// Calculate start point of 2nd straight line (endx1, endy1)
|
|
|
|
var midX1 = startX + ((endX - startX) / 3),
|
|
|
|
midX2 = startX + (2 * ((endX - startX) / 3));
|
|
|
|
|
|
|
|
//create arrow head
|
|
|
|
var arrow = g.polygon(
|
|
|
|
[0, ARROW_HEIGHT,
|
|
|
|
(ARROW_WIDTH / 2), ARROW_HEIGHT,
|
|
|
|
(ARROW_HEIGHT / 4), 0,
|
|
|
|
0, ARROW_WIDTH,
|
|
|
|
]
|
|
|
|
).transform('r90');
|
|
|
|
var marker = arrow.marker(
|
|
|
|
0, 0, ARROW_WIDTH, ARROW_HEIGHT, 0, (ARROW_WIDTH / 2)
|
|
|
|
).attr(arrowOpts);
|
|
|
|
|
|
|
|
// First straight line
|
|
|
|
g.line(
|
|
|
|
startX, startY, midX1, startY
|
|
|
|
).attr(opts);
|
|
|
|
|
|
|
|
// Diagonal line
|
|
|
|
g.line(
|
|
|
|
midX1 - 1, startY, midX2, endY
|
|
|
|
).attr(opts);
|
|
|
|
|
|
|
|
// Last straight line
|
|
|
|
var line = g.line(
|
|
|
|
midX2, endY, endX, endY
|
|
|
|
).attr(opts);
|
|
|
|
line.attr({
|
|
|
|
markerEnd: marker,
|
2018-12-13 04:49:56 -06:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
drawImage: function(
|
|
|
|
g, image_content, currentXpos, currentYpos, graphContainer,
|
2021-12-06 08:37:11 -06:00
|
|
|
toolTipContainer, downloadSVG=false
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
) {
|
2018-01-12 01:29:51 -06:00
|
|
|
// Draw the actual image for current node
|
|
|
|
var image = g.image(
|
2018-12-13 04:49:56 -06:00
|
|
|
image_content,
|
2018-01-12 01:29:51 -06:00
|
|
|
currentXpos + (pWIDTH - IMAGE_WIDTH) / 2,
|
|
|
|
currentYpos + (pHEIGHT - IMAGE_HEIGHT) / 2,
|
|
|
|
IMAGE_WIDTH,
|
|
|
|
IMAGE_HEIGHT
|
|
|
|
);
|
2021-01-20 06:19:23 -06:00
|
|
|
image.attr({
|
|
|
|
style: 'cursor: pointer',
|
|
|
|
class: 'image-node',
|
|
|
|
});
|
2018-01-12 01:29:51 -06:00
|
|
|
|
|
|
|
// Draw tooltip
|
2021-01-12 05:13:30 -06:00
|
|
|
var image_data = this.toJSON(),
|
|
|
|
nodeLabel = this.getLabel();
|
2021-12-06 08:37:11 -06:00
|
|
|
|
|
|
|
if (downloadSVG) {
|
|
|
|
var title = '<title>';
|
|
|
|
_.each(image_data, function (value, key) {
|
|
|
|
if (
|
|
|
|
key !== 'image' &&
|
|
|
|
key !== 'Plans' &&
|
|
|
|
key !== 'level' &&
|
|
|
|
key !== 'image' &&
|
|
|
|
key !== 'image_text' &&
|
|
|
|
key !== 'xpos' &&
|
|
|
|
key !== 'ypos' &&
|
|
|
|
key !== 'width' &&
|
|
|
|
key !== 'height'
|
|
|
|
) {
|
|
|
|
title += `${key}: ${value}\n`;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
title += '</title>';
|
|
|
|
|
|
|
|
image.append(Snap.parse(title));
|
|
|
|
|
|
|
|
image.mouseover(() => {
|
|
|
|
// Empty the tooltip content if it has any and add new data
|
|
|
|
let toolTipBody = toolTipContainer.find('.details-body');
|
|
|
|
let toolTipTitle = toolTipContainer.find('.details-title');
|
|
|
|
toolTipTitle.text(nodeLabel);
|
|
|
|
|
|
|
|
toolTipBody.empty();
|
|
|
|
|
|
|
|
// Remove the title content so that we can show our custom build tooltips.
|
|
|
|
image.node.textContent = '';
|
|
|
|
|
|
|
|
var tooltipTable = $(`
|
|
|
|
<table class='pgadmin-tooltip-table table table-bordered table-noouter-border table-bottom-border table-hover'>
|
|
|
|
<tbody></tbody>
|
|
|
|
</table>`).appendTo(toolTipBody);
|
|
|
|
var tooltip = tooltipTable.find('tbody');
|
|
|
|
|
|
|
|
_.each(image_data, function (value, key) {
|
|
|
|
if (
|
|
|
|
key !== 'image' &&
|
|
|
|
key !== 'Plans' &&
|
|
|
|
key !== 'level' &&
|
|
|
|
key !== 'image' &&
|
|
|
|
key !== 'image_text' &&
|
|
|
|
key !== 'xpos' &&
|
|
|
|
key !== 'ypos' &&
|
|
|
|
key !== 'width' &&
|
|
|
|
key !== 'height'
|
|
|
|
) {
|
|
|
|
key = _.escape(key);
|
|
|
|
value = _.escape(value);
|
|
|
|
tooltip.append(`
|
|
|
|
<tr>
|
|
|
|
<td class='label explain-tooltip'>${key}</td>
|
|
|
|
<td class='label explain-tooltip-val'>${value}</td>
|
|
|
|
</tr>
|
|
|
|
`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
toolTipContainer.removeClass('d-none');
|
|
|
|
toolTipBody.scrollTop(0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-01-12 05:13:30 -06:00
|
|
|
image.click(() => {
|
2018-01-12 01:29:51 -06:00
|
|
|
// Empty the tooltip content if it has any and add new data
|
2021-01-12 05:13:30 -06:00
|
|
|
let toolTipBody = toolTipContainer.find('.details-body');
|
|
|
|
let toolTipTitle = toolTipContainer.find('.details-title');
|
|
|
|
toolTipTitle.text(nodeLabel);
|
|
|
|
|
|
|
|
toolTipBody.empty();
|
2018-12-13 04:49:56 -06:00
|
|
|
|
|
|
|
// Remove the title content so that we can show our custom build tooltips.
|
|
|
|
image.node.textContent = '';
|
|
|
|
|
2021-01-12 05:13:30 -06:00
|
|
|
var tooltipTable = $(`
|
|
|
|
<table class='pgadmin-tooltip-table table table-bordered table-noouter-border table-bottom-border table-hover'>
|
|
|
|
<tbody></tbody>
|
|
|
|
</table>`
|
|
|
|
).appendTo(toolTipBody);
|
|
|
|
var tooltip = tooltipTable.find('tbody');
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
_.each(image_data, function(value, key) {
|
|
|
|
if (key !== 'image' && key !== 'Plans' &&
|
|
|
|
key !== 'level' && key !== 'image' &&
|
|
|
|
key !== 'image_text' && key !== 'xpos' &&
|
|
|
|
key !== 'ypos' && key !== 'width' &&
|
|
|
|
key !== 'height') {
|
2018-12-20 04:09:11 -06:00
|
|
|
key = _.escape(key);
|
|
|
|
value = _.escape(value);
|
|
|
|
tooltip.append(`
|
|
|
|
<tr>
|
|
|
|
<td class="label explain-tooltip">${key}</td>
|
|
|
|
<td class="label explain-tooltip-val">${value}</td>
|
|
|
|
</tr>
|
|
|
|
`);
|
2018-01-12 01:29:51 -06:00
|
|
|
}
|
|
|
|
});
|
2021-01-12 05:13:30 -06:00
|
|
|
toolTipContainer.removeClass('d-none');
|
|
|
|
toolTipBody.scrollTop(0);
|
2018-01-12 01:29:51 -06:00
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2019-05-30 07:19:43 -05:00
|
|
|
/*
|
|
|
|
* NOTE: embedding using .toDataURL() method hits the performance of the
|
|
|
|
* plan rendering a lot, that is why we have written seprate Model for the same
|
|
|
|
* which is used only when downloading of SVG is called
|
|
|
|
*/
|
|
|
|
// We override the PlanModel's draw() function so that we can embbed all the
|
|
|
|
// svg in to main one SVG so that we can download it.
|
|
|
|
let DownloadPlanModel = PlanModel.extend({
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
_createSame: function() {
|
|
|
|
return new DownloadPlanModel({parse: true});
|
2019-05-30 07:19:43 -05:00
|
|
|
},
|
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
_drawImage: function (
|
|
|
|
s, g, image_url, startX, startY, graphContainer, toolTipContainer, _ctx
|
|
|
|
) {
|
2019-05-30 07:19:43 -05:00
|
|
|
/* Check the current browser, if it is Internet Explorer then we will not
|
|
|
|
* embed the SVG files for download feature as we are not bale to figure
|
|
|
|
* out the solution for IE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
var current_browser = pgAdmin.Browser.get_browser();
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
if (current_browser.name === 'IE' || (
|
|
|
|
current_browser.name === 'Safari' &&
|
|
|
|
parseInt(current_browser.version) < 10
|
|
|
|
)) {
|
|
|
|
this.drawImage(
|
|
|
|
g, image_url, startX, startY, graphContainer, toolTipContainer
|
|
|
|
);
|
2019-05-30 07:19:43 -05:00
|
|
|
} else {
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
/* This function is a callback function called when we load any svg
|
|
|
|
* file using Snap. In this function we append the SVG binary data to
|
|
|
|
* the new temporary Snap object and then embedded it to the original
|
|
|
|
* Snap() object.
|
2019-05-30 07:19:43 -05:00
|
|
|
*/
|
|
|
|
var that = this;
|
|
|
|
var onSVGLoaded = function(data) {
|
|
|
|
var svg_image = Snap();
|
|
|
|
svg_image.append(data);
|
2021-12-06 08:37:11 -06:00
|
|
|
var downloadSVG = true;
|
2019-05-30 07:19:43 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
that.drawImage(
|
|
|
|
g, svg_image.toDataURL(), startX, startY, graphContainer,
|
2021-12-06 08:37:11 -06:00
|
|
|
toolTipContainer, downloadSVG
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
);
|
2019-05-30 07:19:43 -05:00
|
|
|
|
|
|
|
// This attribute is required to download the file as SVG image.
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
s.parent().attr({
|
|
|
|
'xmlns:xlink':'http://www.w3.org/1999/xlink',
|
|
|
|
});
|
2019-05-30 07:19:43 -05:00
|
|
|
setTimeout(() => {
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
_ctx._onImageDownloaded();
|
2019-05-30 07:19:43 -05:00
|
|
|
}, 100);
|
|
|
|
};
|
|
|
|
|
|
|
|
var svg_file = pgExplain.prefix + this.get('image');
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
|
2019-05-30 07:19:43 -05:00
|
|
|
// Load the SVG file for explain plan
|
|
|
|
Snap.load(svg_file, onSVGLoaded);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Main backbone model to store JSON object
|
|
|
|
var MainPlanModel = Backbone.Model.extend({
|
2016-05-15 14:37:52 -05:00
|
|
|
defaults: {
|
2018-01-12 01:29:51 -06:00
|
|
|
'Plan': undefined,
|
|
|
|
xpos: 0,
|
|
|
|
ypos: 0,
|
2016-05-15 14:37:52 -05:00
|
|
|
},
|
|
|
|
initialize: function() {
|
2018-01-12 01:29:51 -06:00
|
|
|
this.set('Plan', new PlanModel());
|
2018-07-06 07:13:14 -05:00
|
|
|
this.set('Statistics', new StatisticsModel());
|
2016-05-15 14:37:52 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
// Parse the JSON data and fetch its children plans
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
parse: function(data, _opt) {
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
if (data && 'Plan' in data) {
|
|
|
|
var plan = this.get('Plan');
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
plan.set(plan.parse(
|
|
|
|
_.extend(
|
|
|
|
data['Plan'], {
|
|
|
|
xpos: 0,
|
|
|
|
ypos: 0,
|
|
|
|
}), _opt
|
|
|
|
));
|
2018-01-12 01:29:51 -06:00
|
|
|
|
|
|
|
data['xpos'] = 0;
|
|
|
|
data['ypos'] = 0;
|
|
|
|
data['width'] = plan.get('width') + (xMargin * 2);
|
|
|
|
data['height'] = plan.get('height') + (yMargin * 4);
|
|
|
|
|
|
|
|
delete data['Plan'];
|
|
|
|
}
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-07-06 07:13:14 -05:00
|
|
|
var statistics = this.get('Statistics');
|
|
|
|
if (data && 'JIT' in data) {
|
|
|
|
statistics.set('JIT', data['JIT']);
|
|
|
|
delete data ['JIT'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data && 'Triggers' in data) {
|
|
|
|
statistics.set('Triggers', data['Triggers']);
|
|
|
|
delete data ['Triggers'];
|
|
|
|
}
|
|
|
|
|
2019-07-03 07:57:56 -05:00
|
|
|
if(data) {
|
|
|
|
let summKeys = ['Planning Time', 'Execution Time'],
|
|
|
|
summary = {};
|
|
|
|
|
|
|
|
summKeys.forEach((key)=>{
|
|
|
|
if (key in data) {
|
|
|
|
summary[key] = data[key];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
statistics.set('Summary', summary);
|
|
|
|
}
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
if (data && 'Settings' in data) {
|
|
|
|
statistics.set('Settings', data['Settings']);
|
|
|
|
delete data ['Settings'];
|
|
|
|
}
|
2019-07-03 07:57:56 -05:00
|
|
|
|
2016-05-15 14:37:52 -05:00
|
|
|
return data;
|
|
|
|
},
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
|
2016-05-15 14:37:52 -05:00
|
|
|
toJSON: function() {
|
|
|
|
var res = Backbone.Model.prototype.toJSON.apply(this, arguments);
|
|
|
|
|
|
|
|
if (res.Plan) {
|
|
|
|
res.Plan = res.Plan.toJSON();
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
},
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
|
|
|
|
draw: function(s, xpos, ypos, graphContainer, toolTipContainer, _ctx) {
|
2018-01-12 01:29:51 -06:00
|
|
|
var g = s.g();
|
2020-09-17 09:47:54 -05:00
|
|
|
var colorBg = getComputedStyle(document.documentElement).getPropertyValue('--color-bg');
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
//draw the border
|
|
|
|
g.rect(
|
|
|
|
0, 0, this.get('width') - 10, this.get('height') - 10, 5
|
|
|
|
).attr({
|
2020-09-17 09:47:54 -05:00
|
|
|
fill: colorBg,
|
2018-01-12 01:29:51 -06:00
|
|
|
});
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
var plan = this.get('Plan');
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Draw explain graph
|
|
|
|
plan.draw(
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
g, xpos, ypos, undefined, undefined, graphContainer, toolTipContainer,
|
|
|
|
_ctx
|
2018-01-12 01:29:51 -06:00
|
|
|
);
|
2018-07-06 07:13:14 -05:00
|
|
|
|
|
|
|
//Set the Statistics as tooltip
|
|
|
|
var statistics = this.get('Statistics');
|
|
|
|
statistics.set_statistics(toolTipContainer);
|
2018-01-12 01:29:51 -06:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
var _createContainer = function() {
|
|
|
|
_createContainer.cnt = (_createContainer.cnt || 0) + 1;
|
|
|
|
let id = _createContainer.cnt,
|
|
|
|
createTab = (_idx, _type, _label, _active) => {
|
|
|
|
return [
|
|
|
|
' <li class="nav-item" role="presentation">',
|
|
|
|
' <a class="nav-link ', _active ? 'active' : '', '"',
|
2019-12-31 23:21:45 -06:00
|
|
|
' data-toggle="tab" tabindex="0"',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
` data-tab-index="${_idx}"`,
|
|
|
|
' aria-selected="', _active ? 'true' : 'false', '"',
|
|
|
|
` role="tab" data-explain-role="${_type}"`,
|
|
|
|
` href="#pga_explain_${_type}_${id}"`,
|
|
|
|
` aria-controls="pga_explain_${_type}_${id}"`,
|
|
|
|
` id="pgah_explain_${_type}_${id}"> `,
|
|
|
|
_label, '</a>', '</li>',
|
|
|
|
].join('');
|
|
|
|
},
|
|
|
|
createTabPanel = (_type, _active, _extraClasses) => {
|
|
|
|
return [
|
2019-12-31 23:21:45 -06:00
|
|
|
' <div role="tabpanel" tabindex="0" class="tab-pane pg-el-sm-12',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
' pg-el-md-12 pg-el-lg-12 pg-el-12 fade collapse',
|
|
|
|
_active ? ' active show' : '', ` ${_extraClasses}"`,
|
|
|
|
` data-explain-tabpanel="${_type}"`,
|
|
|
|
` id="pga_explain_${_type}_${id}"`,
|
|
|
|
` aria-labelledby="pgah_explain_${_type}_${id}">`,
|
|
|
|
' </div>',
|
|
|
|
].join('');
|
|
|
|
};
|
|
|
|
return $([
|
|
|
|
'<div class="obj_properties container-fluid">',
|
|
|
|
' <div tabindex="1" class="backform-tab pg-el-12" role="tabpanel">',
|
|
|
|
' <ul class="nav nav-tabs" role="tablist">',
|
|
|
|
' </li>',
|
|
|
|
' <li class="nav-item" role="presentation">',
|
|
|
|
createTab(1, 'graphical', gettext('Graphical'), true),
|
|
|
|
createTab(2, 'table', gettext('Analysis'), false),
|
|
|
|
createTab(3, 'statistics', gettext('Statistics'), false),
|
|
|
|
' </ul>',
|
|
|
|
' <div class="tab-content pg-el-sm-12 pg-el-12">',
|
|
|
|
createTabPanel('graphical', true, 'w-100 h-100 p-0'),
|
|
|
|
createTabPanel('table', false, 'p-0'),
|
|
|
|
createTabPanel('statistics', false, ''),
|
|
|
|
' </div>',
|
|
|
|
' </div>',
|
|
|
|
' </div>',
|
|
|
|
'</div>',
|
|
|
|
].join(''));
|
|
|
|
};
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Parse and draw full graphical explain
|
|
|
|
_.extend(pgExplain, {
|
|
|
|
// Assumption container is a jQuery object
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
DrawJSONPlan: function(container, plan, isDownload, _ctx) {
|
2019-10-10 01:35:28 -05:00
|
|
|
let self = this;
|
2021-02-10 01:17:52 -06:00
|
|
|
require.ensure(['snap.svg'], function(require) {
|
|
|
|
var module = require('snap.svg');
|
2019-10-10 01:35:28 -05:00
|
|
|
initSnap(module);
|
|
|
|
self.goForDraw(container, plan, isDownload, _ctx);
|
|
|
|
}, function(error){
|
|
|
|
throw(error);
|
|
|
|
}, 'snapsvg');
|
|
|
|
},
|
|
|
|
|
|
|
|
// Assumption container is a jQuery object
|
|
|
|
goForDraw: function(container, plan, isDownload, _ctx) {
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
var ctx = _.extend(_ctx || {}, {
|
|
|
|
totalNodes: 0,
|
|
|
|
totalDownloadedNodes: 0,
|
|
|
|
isDownloaded: 0,
|
|
|
|
});
|
|
|
|
|
|
|
|
container.empty()
|
|
|
|
.attr('el', 'sm').addClass('pg-no-overflow pg-el-container');
|
|
|
|
|
|
|
|
var explainContainer = _createContainer(),
|
|
|
|
explainTable = _createExplainTable(),
|
|
|
|
statisticsTables = _createStatisticsTables(),
|
|
|
|
graphicalContainer = explainContainer.find(
|
|
|
|
'[data-explain-tabpanel=graphical]'
|
|
|
|
),
|
|
|
|
tableContainer = explainContainer.find(
|
|
|
|
'[data-explain-tabpanel=table]'
|
|
|
|
);
|
|
|
|
|
|
|
|
ctx.currentTab = container.find(
|
|
|
|
'.nav-link[aria-selected=true]'
|
|
|
|
).attr('data-explain-role');
|
|
|
|
|
|
|
|
explainContainer.appendTo(container);
|
|
|
|
explainTable.appendTo(tableContainer);
|
|
|
|
statisticsTables.appendTo(explainContainer.find(
|
|
|
|
'[data-explain-tabpanel=statistics]'
|
|
|
|
));
|
|
|
|
|
2019-05-30 07:19:43 -05:00
|
|
|
var orignalPlan = $.extend(true, [], plan);
|
2018-01-12 01:29:51 -06:00
|
|
|
var curr_zoom_factor = 1.0;
|
|
|
|
|
|
|
|
var zoomArea = $('<div></div>', {
|
2019-10-10 01:35:28 -05:00
|
|
|
class: 'pg-explain-zoom-area btn-group btn-group-sm',
|
2018-01-12 01:29:51 -06:00
|
|
|
role: 'group',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}).appendTo(graphicalContainer),
|
2018-01-12 01:29:51 -06:00
|
|
|
zoomInBtn = $('<button></button>', {
|
2020-07-20 01:21:21 -05:00
|
|
|
class: 'btn btn-primary-icon pg-explain-zoom-btn',
|
2019-12-31 01:35:46 -06:00
|
|
|
title: gettext('Zoom in'),
|
|
|
|
'aria-label': gettext('Zoom in'),
|
2018-01-25 06:27:13 -06:00
|
|
|
tabindex: 0,
|
2018-01-12 01:29:51 -06:00
|
|
|
}).appendTo(zoomArea).append(
|
|
|
|
$('<i></i>', {
|
|
|
|
class: 'fa fa-search-plus',
|
|
|
|
})),
|
|
|
|
zoomToNormal = $('<button></button>', {
|
2020-07-20 01:21:21 -05:00
|
|
|
class: 'btn btn-primary-icon pg-explain-zoom-btn',
|
2019-12-31 01:35:46 -06:00
|
|
|
title: gettext('Zoom to original'),
|
|
|
|
'aria-label': gettext('Zoom to original'),
|
2018-01-25 06:27:13 -06:00
|
|
|
tabindex: 0,
|
2018-01-12 01:29:51 -06:00
|
|
|
}).appendTo(zoomArea).append(
|
|
|
|
$('<i></i>', {
|
|
|
|
class: 'fa fa-arrows-alt',
|
|
|
|
})),
|
|
|
|
zoomOutBtn = $('<button></button>', {
|
2020-07-20 01:21:21 -05:00
|
|
|
class: 'btn btn-primary-icon pg-explain-zoom-btn',
|
2019-12-31 01:35:46 -06:00
|
|
|
title: gettext('Zoom out'),
|
|
|
|
'aria-label': gettext('Zoom out'),
|
2018-01-25 06:27:13 -06:00
|
|
|
tabindex: 0,
|
2018-01-12 01:29:51 -06:00
|
|
|
}).appendTo(zoomArea).append(
|
|
|
|
$('<i></i>', {
|
|
|
|
class: 'fa fa-search-minus',
|
|
|
|
}));
|
|
|
|
|
2018-12-13 04:49:56 -06:00
|
|
|
var downloadArea = $('<div></div>', {
|
2019-10-10 01:35:28 -05:00
|
|
|
class: 'pg-explain-download-area btn-group btn-group-sm',
|
2018-12-13 04:49:56 -06:00
|
|
|
role: 'group',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}).appendTo(graphicalContainer),
|
2018-12-13 04:49:56 -06:00
|
|
|
downloadBtn = $('<button></button>', {
|
|
|
|
id: 'btn-explain-download',
|
2020-07-20 01:21:21 -05:00
|
|
|
class: 'btn btn-primary-icon pg-explain-download-btn',
|
2019-12-31 01:35:46 -06:00
|
|
|
title: gettext('Download'),
|
|
|
|
'aria-label': gettext('Download'),
|
2018-12-13 04:49:56 -06:00
|
|
|
tabindex: 0,
|
|
|
|
disabled: function() {
|
|
|
|
var current_browser = pgAdmin.Browser.get_browser();
|
|
|
|
if (current_browser.name === 'IE') {
|
|
|
|
this.title = 'Not supported for Internet Explorer';
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (current_browser.name === 'Safari' &&
|
|
|
|
parseInt(current_browser.version) < 10) {
|
|
|
|
this.title = 'Not supported for Safari version less than 10.1';
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
}).appendTo(downloadArea).append(
|
|
|
|
$('<i></i>', {
|
|
|
|
class: 'fa fa-download',
|
|
|
|
}));
|
|
|
|
|
2018-07-06 07:13:14 -05:00
|
|
|
var statsArea = $('<div></div>', {
|
2019-10-10 01:35:28 -05:00
|
|
|
class: 'pg-explain-stats-area btn-group btn-group-sm d-none',
|
2018-07-06 07:13:14 -05:00
|
|
|
role: 'group',
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
}).appendTo(graphicalContainer);
|
2018-07-06 07:13:14 -05:00
|
|
|
|
|
|
|
$('<button></button>', {
|
|
|
|
id: 'btn-explain-stats',
|
2020-07-20 01:21:21 -05:00
|
|
|
class: 'btn btn-primary-icon pg-explain-stats-btn',
|
2019-12-31 01:35:46 -06:00
|
|
|
title: gettext('Statistics'),
|
|
|
|
'aria-label': gettext('Statistics'),
|
2018-07-06 07:13:14 -05:00
|
|
|
tabindex: 0,
|
|
|
|
}).appendTo(statsArea).append(
|
|
|
|
$('<i></i>', {
|
2020-08-13 01:34:00 -05:00
|
|
|
class: 'fa fa-chart-line',
|
2018-07-06 07:13:14 -05:00
|
|
|
}));
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
// Main div to be drawn all images on
|
|
|
|
var planDiv = $('<div></div>', {
|
2021-01-12 05:13:30 -06:00
|
|
|
class: 'pgadmin-explain-container w-100 h-100 overflow-auto',
|
|
|
|
}).appendTo(graphicalContainer);
|
2018-01-12 01:29:51 -06:00
|
|
|
planDiv.data('zoom-factor', curr_zoom_factor);
|
|
|
|
|
2021-01-12 05:13:30 -06:00
|
|
|
var explainDetails = $(
|
|
|
|
`<div class="pgadmin-explain-details card d-none" data-bs-backdrop="false" tabindex="-1" aria-hidden="true">
|
|
|
|
<div class="card-header details-header d-flex">
|
|
|
|
<div class="details-title my-auto"></div>
|
|
|
|
<div class="ml-auto"><button class="btn btn-sm fa fa-times ml-auto details-close"/></div>
|
|
|
|
</div>
|
|
|
|
<div class="card-body details-body"></div>
|
|
|
|
</div>`
|
|
|
|
).appendTo(graphicalContainer);
|
|
|
|
explainDetails.find('.details-close').on('click', ()=>{
|
|
|
|
explainDetails.addClass('d-none');
|
|
|
|
});
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
var w = 0,
|
|
|
|
h = yMargin;
|
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
ctx._explainTable = {
|
|
|
|
rows: [],
|
|
|
|
statistics: {
|
|
|
|
tables: {},
|
|
|
|
nodes: {},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
ctx._onImageDownloaded = () => {
|
|
|
|
ctx.totalDownloadedNodes++;
|
|
|
|
if (!ctx.isDownloaded && ctx.totalNodes === ctx.totalDownloadedNodes) {
|
|
|
|
ctx.isDownloaded = true;
|
|
|
|
var s = Snap(
|
|
|
|
`#${graphicalContainer.attr('id')} .pgadmin-explain-container svg`
|
|
|
|
);
|
|
|
|
var today = new Date();
|
|
|
|
var filename = 'explain_plan_' + today.getTime() + '.svg';
|
|
|
|
svgDownloader.downloadSVG(s.toString(), filename);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Lets regenrate the plan with embedded images
|
2018-01-12 01:29:51 -06:00
|
|
|
_.each(plan, function(p) {
|
2019-05-30 07:19:43 -05:00
|
|
|
var main_plan;
|
|
|
|
if(isDownload) {
|
|
|
|
// If user opt to download then we will use the DownloadPlanModel model
|
|
|
|
// so that it will embed the images while regenrating the plan
|
|
|
|
let DownloadMainPlanModel = MainPlanModel.extend({
|
|
|
|
initialize: function() {
|
|
|
|
this.set('Plan', new DownloadPlanModel({ parse: true }));
|
|
|
|
this.set('Statistics', new StatisticsModel());
|
|
|
|
},
|
|
|
|
});
|
|
|
|
main_plan = new DownloadMainPlanModel({ 'parse': true });
|
|
|
|
} else {
|
|
|
|
main_plan = new MainPlanModel();
|
|
|
|
}
|
2018-01-12 01:29:51 -06:00
|
|
|
|
|
|
|
// Parse JSON data to backbone model
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
main_plan.set(main_plan.parse(p, {ctx: ctx}));
|
2018-01-12 01:29:51 -06:00
|
|
|
w = main_plan.get('width');
|
|
|
|
h = main_plan.get('height');
|
|
|
|
|
|
|
|
var s = Snap(w, h),
|
|
|
|
$svg = $(s.node).detach();
|
|
|
|
planDiv.append($svg);
|
2021-01-12 05:13:30 -06:00
|
|
|
main_plan.draw(s, w - xMargin, yMargin, planDiv, explainDetails, ctx);
|
2018-01-12 01:29:51 -06:00
|
|
|
|
|
|
|
var initPanelWidth = planDiv.width();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Scale graph in case its width is bigger than panel width
|
|
|
|
* in which the graph is displayed
|
|
|
|
*/
|
|
|
|
if (initPanelWidth < w) {
|
|
|
|
var width_ratio = initPanelWidth / w;
|
|
|
|
|
|
|
|
curr_zoom_factor = width_ratio;
|
|
|
|
curr_zoom_factor = curr_zoom_factor < MIN_ZOOM_FACTOR ? MIN_ZOOM_FACTOR : curr_zoom_factor;
|
|
|
|
curr_zoom_factor = curr_zoom_factor > INIT_ZOOM_FACTOR ? INIT_ZOOM_FACTOR : curr_zoom_factor;
|
|
|
|
|
2020-07-16 09:23:39 -05:00
|
|
|
let zoomInMatrix = new Snap.matrix();
|
2018-01-12 01:29:51 -06:00
|
|
|
zoomInMatrix.scale(curr_zoom_factor, curr_zoom_factor);
|
|
|
|
|
|
|
|
$svg.find('g').first().attr({
|
|
|
|
transform: zoomInMatrix,
|
|
|
|
});
|
|
|
|
$svg.attr({
|
|
|
|
'width': w * curr_zoom_factor,
|
|
|
|
'height': h * curr_zoom_factor,
|
|
|
|
});
|
|
|
|
planDiv.data('zoom-factor', curr_zoom_factor);
|
|
|
|
}
|
|
|
|
|
|
|
|
zoomInBtn.on('click', function() {
|
|
|
|
curr_zoom_factor = ((curr_zoom_factor + ZOOM_RATIO) > MAX_ZOOM_FACTOR) ? MAX_ZOOM_FACTOR : (curr_zoom_factor + ZOOM_RATIO);
|
2020-07-16 09:23:39 -05:00
|
|
|
let zoomInMatrix = new Snap.matrix();
|
2018-01-12 01:29:51 -06:00
|
|
|
zoomInMatrix.scale(curr_zoom_factor, curr_zoom_factor);
|
|
|
|
|
|
|
|
$svg.find('g').first().attr({
|
|
|
|
transform: zoomInMatrix,
|
|
|
|
});
|
|
|
|
$svg.attr({
|
|
|
|
'width': w * curr_zoom_factor,
|
|
|
|
'height': h * curr_zoom_factor,
|
|
|
|
});
|
|
|
|
planDiv.data('zoom-factor', curr_zoom_factor);
|
|
|
|
});
|
|
|
|
|
|
|
|
zoomOutBtn.on('click', function() {
|
|
|
|
curr_zoom_factor = ((curr_zoom_factor - ZOOM_RATIO) < MIN_ZOOM_FACTOR) ? MIN_ZOOM_FACTOR : (curr_zoom_factor - ZOOM_RATIO);
|
2020-07-16 09:23:39 -05:00
|
|
|
let zoomInMatrix = new Snap.matrix();
|
2018-01-12 01:29:51 -06:00
|
|
|
zoomInMatrix.scale(curr_zoom_factor, curr_zoom_factor);
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
$svg.find('g').first().attr({
|
|
|
|
transform: zoomInMatrix,
|
|
|
|
});
|
|
|
|
$svg.attr({
|
|
|
|
'width': w * curr_zoom_factor,
|
|
|
|
'height': h * curr_zoom_factor,
|
|
|
|
});
|
2016-05-15 14:37:52 -05:00
|
|
|
planDiv.data('zoom-factor', curr_zoom_factor);
|
2018-01-12 01:29:51 -06:00
|
|
|
});
|
2016-05-15 14:37:52 -05:00
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
zoomToNormal.on('click', function() {
|
|
|
|
curr_zoom_factor = INIT_ZOOM_FACTOR;
|
2020-07-16 09:23:39 -05:00
|
|
|
let zoomInMatrix = new Snap.matrix();
|
2018-01-12 01:29:51 -06:00
|
|
|
zoomInMatrix.scale(curr_zoom_factor, curr_zoom_factor);
|
|
|
|
|
|
|
|
$svg.find('g').first().attr({
|
|
|
|
transform: zoomInMatrix,
|
|
|
|
});
|
|
|
|
$svg.attr({
|
|
|
|
'width': w * curr_zoom_factor,
|
|
|
|
'height': h * curr_zoom_factor,
|
2016-05-15 14:37:52 -05:00
|
|
|
});
|
2018-01-12 01:29:51 -06:00
|
|
|
planDiv.data('zoom-factor', curr_zoom_factor);
|
|
|
|
});
|
2018-12-13 04:49:56 -06:00
|
|
|
|
|
|
|
downloadBtn.on('click', function() {
|
2019-05-30 07:19:43 -05:00
|
|
|
pgExplain.DrawJSONPlan(container, orignalPlan, true);
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
planDiv.on('explain:svg:downloaded', function() {
|
|
|
|
ctx.totalDownloadedNodes++;
|
|
|
|
if (!ctx.isDownloaded && ctx.totalNodes === ctx.totalDownloadedNodes) {
|
|
|
|
ctx.isDownloaded = true;
|
2021-03-02 03:23:05 -06:00
|
|
|
s = Snap('.pgadmin-explain-container svg');
|
2019-05-30 07:19:43 -05:00
|
|
|
var today = new Date();
|
|
|
|
var filename = 'explain_plan_' + today.getTime() + '.svg';
|
|
|
|
svgDownloader.downloadSVG(s.toString(), filename);
|
|
|
|
}
|
|
|
|
});
|
2018-12-13 04:49:56 -06:00
|
|
|
});
|
2021-01-20 06:19:23 -06:00
|
|
|
container.find('.image-node').tooltip({
|
|
|
|
title: gettext('Click for details...'),
|
|
|
|
template: '<div class="tooltip" role="tooltip"><div class="arrow d-none"></div><div class="tooltip-inner"></div></div>',
|
|
|
|
});
|
2018-01-12 01:29:51 -06:00
|
|
|
});
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
|
|
|
|
_renderExplainTable(ctx._explainTable, explainTable);
|
|
|
|
|
|
|
|
_renderStatisticsTable(ctx._explainTable, statisticsTables);
|
|
|
|
|
|
|
|
container.on('shown.bs.tab', function() {
|
|
|
|
ctx.currentTab = container.find(
|
|
|
|
'.nav-link[aria-selected=true]'
|
|
|
|
).attr('data-explain-role');
|
|
|
|
});
|
2018-01-12 01:29:51 -06:00
|
|
|
},
|
|
|
|
});
|
2016-05-15 14:37:52 -05:00
|
|
|
|
Fixes # 4778 - Implement the query plan analyzer
Look 'n' Feel and implementation logic are inspired from
'http://explain.depsez.com'.
It now creates three tabs under the 'Explain' panel when executing a
query using the Explain Analyze/Explain button from the toolbar of the
Query tool.
Graphical
---------
-> Graphical Explain Plan
Analysis
--------
-> Table to show details of the explain plan analyse.
-> Each row represents the statistics per Explain Plan Node
-> It may contains columns like node information, exclusive timing
(time spent for this explain node excluding the child nodes),
inclusive timing, actual rows, plan rows,
rowsx (misestimation between planned vs actual rows), loop.
-> Background color of exclusive, inclusive, rows changes based on
their values.
i.e.
If Percentage of exclusive, and inclusive timings of total query time
is:
> 90 - Red Color
> 50 - Orange (Between Red & Yellow Color)
> 10 - Yellow color
If planner misestimation for the rows is
> 1000 times - Red Color
> 100 times - Orange (Between Red & Yellow Color)
> 10 times - Yellow Color
Also - if actual rows <= planned rows then it shows up arrow, else it
shows down arrow.
Statistics
----------
-> It contains a HTML table for the statistics per Node Type, and
a HTML table for the statistics per table.
Reviewed by: Akshay Joshi
2019-10-08 06:03:25 -05:00
|
|
|
$(document)
|
|
|
|
.on('mouseenter', '.pga-ex-row.pga-ex-collapsible', function(ev) {
|
|
|
|
let $target = $(ev.currentTarget);
|
|
|
|
|
|
|
|
$target.parent().find(
|
|
|
|
'[data-parent=' + $target.attr('data-ex-id') +
|
|
|
|
'] > td.pg-ex-highlighter > i'
|
|
|
|
).removeClass('invisible');
|
|
|
|
})
|
|
|
|
.on('mouseleave', '.pga-ex-row.pga-ex-collapsible', function(ev) {
|
|
|
|
let $target = $(ev.currentTarget);
|
|
|
|
|
|
|
|
$target.parent().find(
|
|
|
|
'.pga-ex-row[data-parent=' + $target.attr('data-ex-id') +
|
|
|
|
'] > td.pg-ex-highlighter > i'
|
|
|
|
).addClass('invisible');
|
|
|
|
})
|
|
|
|
.on('click', '.pga-ex-row.pga-ex-collapsible', function(ev) {
|
|
|
|
let $target = $(ev.currentTarget),
|
|
|
|
collapsed = ($target.attr('data-collapsed') === 'true');
|
|
|
|
|
|
|
|
if (collapsed) {
|
|
|
|
$target.parent().find(
|
|
|
|
'.pga-ex-row[data-parent^=' + $target.attr('data-ex-id') + ']'
|
|
|
|
).removeClass('d-none').filter('[data-collapsed=true]').each(
|
|
|
|
function(idx, el) {
|
|
|
|
var $el = $(el);
|
|
|
|
$el.parent().find(
|
|
|
|
'.pga-ex-row[data-parent^=' + $el.attr('data-ex-id') + ']'
|
|
|
|
).addClass('d-none');
|
|
|
|
});
|
|
|
|
$target.attr('data-collapsed', 'false');
|
|
|
|
} else {
|
|
|
|
$target.parent().find(
|
|
|
|
'.pga-ex-row[data-parent^=' + $target.attr('data-ex-id') + ']'
|
|
|
|
).addClass('d-none');
|
|
|
|
$target.attr('data-collapsed', 'true');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-01-12 01:29:51 -06:00
|
|
|
return pgExplain;
|
2016-05-15 14:37:52 -05:00
|
|
|
});
|