From 11ce302be082f1cf3ba00f13a6f36f540f297fce Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Wed, 25 Jun 2014 21:12:44 +0200 Subject: [PATCH] Ido\StatusQuery: fine-tune query filters This is still experimental. We normalize a lot of columns, this allows us to sort in a convenient way while having nice "showable" columns. When used as filters (same goes for ordering) however, functions and operations on table columns often hinder the db from using indexes. The new filter implementation allows us to override query creating per single column, that's what this first sample is trying to show. We still need to fix alias handling, so unfortunately I have to deal with "real columns" in the case construct. Performance gain in large environments is impressive, more to come. --- .../Backend/Ido/Query/StatusQuery.php | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusQuery.php index a83b2fc51..7a9af1524 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusQuery.php @@ -331,6 +331,46 @@ class StatusQuery extends IdoQuery ); } + // Tuning experiments + public function whereToSql($col, $sign, $expression) + { + switch ($col) { + + case 'CASE WHEN ss.current_state = 0 THEN 0 ELSE 1 END': + if ($sign !== '=') break; + + if ($expression) { + return 'ss.current_state > 0'; + } else { + return 'ss.current_state = 0'; + } + break; + + case 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END': + if ($sign !== '=') break; + + if ($expression) { + return 'hs.current_state > 0'; + } else { + return 'hs.current_state = 0'; + } + break; + + case 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE CASE WHEN ss.state_type = 1 THEN ss.current_state ELSE ss.last_hard_state END END': + if ($sign !== '=') break; + if ($expression == 99) { + return 'ss.has_been_checked = 0 OR ss.has_been_checked IS NULL'; + } + if (in_array($expression, array(0, 1, 2, 3))) { + return sprintf('((ss.state_type = 1 AND ss.current_state = %d) OR (ss.state_type = 0 AND ss.last_hard_state = %d))', $expression, $expression); + } + break; + + } + + return parent::whereToSql($col, $sign, $expression); + } + protected function joinStatus() { $this->requireVirtualTable('services');