def evaluate(self, profile, plan_node_id): """ Evaluate the impact of this cause to the query. The return is a json string with this format: { "impact": the amount of slow down (in ns), "message" : the displayed "explanation" string } :return: """ impact = -1 if len(self.exprs): assert len(self.metric_names) == 1 # metric_names can have multiple values create a dict for all of # them db_result = models.query_element_by_metric(profile, 'Summary', self.metric_names[0]) for k, g in groupby(db_result, lambda x: x.fid): grouped = list(g) # A list of pairs, with aggregated value and index at value for # max / min like exprs converted_exprs = self.check_exprs(grouped) expr_vars = { "vars": dict(zip(self.exprs, map(lambda x: x[0], converted_exprs))), "idxs": dict(zip(self.exprs, map(lambda x: x[1], converted_exprs))), } expr_val = exprs.Expr.evaluate(self.rule["expr"], expr_vars) if (impact is None or impact < expr_val): impact = expr_val else: # For each of the metrics get the result with Timer() as t: # Get the metric values from the db grouped by metric name db_result = [models.query_element_by_metric(profile, 'Summary', m) for m in self.metric_names] # Assuming that for all metric names the same number of rows have been returned transpose the array all_metrics = zip(*db_result) for row in all_metrics: # Convert to double values if unit is 6(double) metric_values = map(lambda x: x.value if x.unit != 6 else to_double(x.value), row) local_vars = {"vars": dict(zip(self.metric_names, metric_values))} condition = True if ("condition" in self.rule): condition = exprs.Expr.evaluate(self.rule["condition"], local_vars) if (condition): expr_val = exprs.Expr.evaluate(self.rule["expr"], local_vars) if (impact is None or impact < expr_val): impact = expr_val return { "impact": impact, "message": self.rule["message"], "label": self.rule["label"] }
def evaluate(self, profile, plan_node_id): """ Evaluate the impact of this cause to the query. The return is a json string with this format: { "impact": the amount of slow down (in ns), "message" : the displayed "explanation" string } :return: """ impact = -1 expr_data = '' if len(self.exprs): assert len(self.metric_names) == 1 # metric_names can have multiple values create a dict for all of # them db_result = models.query_node_by_id(profile, plan_node_id, self.metric_names[0]) for k, g in groupby(db_result, lambda x: x.fid): grouped = list(g) # A list of pairs, with aggregated value and index at value for # max / min like exprs converted_exprs = self.check_exprs(grouped) expr_vars = { "vars": dict(zip(self.exprs, map(lambda x: x[0], converted_exprs))), "idxs": dict(zip(self.exprs, map(lambda x: x[1], converted_exprs))), } expr_val = exprs.Expr.evaluate(self.rule["expr"], expr_vars) if (impact is None or impact < expr_val): impact = expr_val else: # For each of the metrics get the result with Timer() as t: # Get the metric values from the db grouped by metric name db_result = [ models.query_node_by_id(profile, plan_node_id, m) for m in self.metric_names ] # Assuming that for all metric names the same number of rows have been returned transpose the array all_metrics = zip(*db_result) for row in all_metrics: # Convert to double values if unit is 6(double) metric_values = map( lambda x: x.value if x.unit != 6 else to_double(x.value), row) surrogate_node = row[0].node local_vars = { "vars": dict(zip(self.metric_names, metric_values)) } local_vars["vars"]["IOBound"] = self.isStorageBound( surrogate_node) local_vars["vars"]['InputRows'] = self.getNumInputRows( surrogate_node) condition = True if ("condition" in self.rule): condition = exprs.Expr.evaluate(self.rule["condition"], local_vars) if (condition): expr_val = exprs.Expr.evaluate(self.rule["expr"], local_vars) if (impact is None or impact < expr_val): impact = expr_val if self.kwargs.get('info_names'): db_result = [ models.query_element_by_info(profile, plan_node_id, m) for m in self.kwargs['info_names'] ] all_metrics = zip(*db_result) for row in all_metrics: metric_values = map(lambda x: x.value, row) local_vars['vars'].update( dict(zip(self.kwargs['info_names'], metric_values))) expr_data = exprs.Expr.evaluate(self.kwargs['fix']['data'], local_vars) msg = self.rule["label"] + ": " + self.rule["message"] return {"impact": impact, "message": msg, "data": expr_data}