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.
This commit is contained in:
Thomas Gelf 2014-06-25 21:12:44 +02:00
parent 86f70e0a4f
commit 11ce302be0
1 changed files with 40 additions and 0 deletions

View File

@ -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');