Additional Execution Plan Node Properties for Highlighting Expensive Operators (#1683)

* Adds cost metric information to the node.

* Gets the elapsed CPU time by the node operation

* Renames DTO property to row metrics

* Removes unused class

* Simplify checks for row property values

* Cleans up model for node cost metrics

* Removes duplicate code

* Switching to primitive type empty string

* Code review changes
This commit is contained in:
Lewis Sanchez
2022-09-29 13:09:37 -07:00
committed by GitHub
parent 7c5d48b111
commit ddfc86fe04
3 changed files with 80 additions and 5 deletions

View File

@@ -63,7 +63,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.Contracts
/// </summary> /// </summary>
public double RelativeCost { get; set; } public double RelativeCost { get; set; }
/// <summary> /// <summary>
/// Time take by the node operation in milliseconds /// Time taken by the node operation in milliseconds
/// </summary> /// </summary>
public long? ElapsedTimeInMs { get; set; } public long? ElapsedTimeInMs { get; set; }
/// <summary> /// <summary>
@@ -92,6 +92,22 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.Contracts
/// Top operations table data for the node /// Top operations table data for the node
/// </summary> /// </summary>
public List<TopOperationsDataItem> TopOperationsData { get; set; } public List<TopOperationsDataItem> TopOperationsData { get; set; }
/// <summary>
/// The cost metrics for the node.
/// </summary>
public List<CostMetric> CostMetrics { get; set; }
}
public class CostMetric
{
/// <summary>
/// Name of the cost metric
/// </summary>
public string Name { get; set; }
/// <summary>
/// The value for the cost metric
/// </summary>
public string Value { get; set; }
} }
public class ExecutionPlanGraphPropertyBase public class ExecutionPlanGraphPropertyBase

View File

@@ -33,8 +33,40 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
}).ToList(); }).ToList();
} }
private static void ParseCostMetricProperty(List<CostMetric> costMetrics, string name, PropertyValue? property)
{
if (property != null)
{
var costMetric = new CostMetric()
{
Name = name,
Value = ExecutionPlanGraphUtils.GetPropertyDisplayValue(property)
};
costMetrics.Add(costMetric);
}
}
public static ExecutionPlanNode ConvertShowPlanTreeToExecutionPlanTree(Node currentNode) public static ExecutionPlanNode ConvertShowPlanTreeToExecutionPlanTree(Node currentNode)
{ {
var costMetrics = new List<CostMetric>();
var elapsedCpuTimeInMs = currentNode.ElapsedCpuTimeInMs;
if (elapsedCpuTimeInMs.HasValue)
{
var costMetric = new CostMetric()
{
Name = "ElapsedCpuTime",
Value = $"{elapsedCpuTimeInMs.Value}"
};
costMetrics.Add(costMetric);
}
ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "EstimateRowsAllExecs", currentNode.Properties["EstimateRowsAllExecs"] as PropertyValue);
ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "EstimatedRowsRead", currentNode.Properties["EstimatedRowsRead"] as PropertyValue);
ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "ActualRows", currentNode.Properties["ActualRows"] as PropertyValue);
ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "ActualRowsRead", currentNode.Properties["ActualRowsRead"] as PropertyValue);
return new ExecutionPlanNode return new ExecutionPlanNode
{ {
ID = currentNode.ID, ID = currentNode.ID,
@@ -52,7 +84,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
Badges = GenerateNodeOverlay(currentNode), Badges = GenerateNodeOverlay(currentNode),
Name = currentNode.DisplayName, Name = currentNode.DisplayName,
ElapsedTimeInMs = currentNode.ElapsedTimeInMs, ElapsedTimeInMs = currentNode.ElapsedTimeInMs,
TopOperationsData = ParseTopOperationsData(currentNode) TopOperationsData = ParseTopOperationsData(currentNode),
CostMetrics = costMetrics
}; };
} }
@@ -134,6 +167,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
propertyDataType = PropertyValueDataType.String; propertyDataType = PropertyValueDataType.String;
break; break;
} }
propsList.Add(new ExecutionPlanGraphProperty() propsList.Add(new ExecutionPlanGraphProperty()
{ {
Name = prop.DisplayName, Name = prop.DisplayName,
@@ -412,8 +446,13 @@ GO
"; ";
} }
private static string GetPropertyDisplayValue(PropertyValue property) private static string GetPropertyDisplayValue(PropertyValue? property)
{ {
if (property == null)
{
return string.Empty;
}
try try
{ {
// Get the property value. // Get the property value.
@@ -421,7 +460,7 @@ GO
if (propertyValue == null) if (propertyValue == null)
{ {
return String.Empty; return string.Empty;
} }
// Convert the property value to the text. // Convert the property value to the text.
@@ -430,7 +469,7 @@ GO
catch (Exception e) catch (Exception e)
{ {
Logger.Write(TraceEventType.Error, e.ToString()); Logger.Write(TraceEventType.Error, e.ToString());
return String.Empty; return string.Empty;
} }
} }

View File

@@ -501,6 +501,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
} }
} }
public long? ElapsedCpuTimeInMs
{
get
{
long? time = null;
var actualStatsWrapper = this["ActualTimeStatistics"] as ExpandableObjectWrapper;
if (actualStatsWrapper != null)
{
var counters = actualStatsWrapper["ActualCPUms"] as RunTimeCounters;
if (counters != null)
{
var elapsedTime = counters.MaxCounter;
long ticks = (long)elapsedTime * TimeSpan.TicksPerMillisecond;
time = new DateTime(ticks).Millisecond;
}
}
return time;
}
}
/// <summary> /// <summary>
/// ENU name for Logical Operator /// ENU name for Logical Operator
/// </summary> /// </summary>