ContactQuery: Don't use a UNION query if not necessary

Speeds up the db's response time significantly in huge
environments.

refs #3088

Signed-off-by: Eric Lippmann <eric.lippmann@icinga.com>
This commit is contained in:
Johannes Meyer 2018-07-17 14:05:32 +02:00 committed by Eric Lippmann
parent 2fbbf3da58
commit 5befab6a2b
2 changed files with 53 additions and 26 deletions

View File

@ -58,6 +58,14 @@ class ContactQuery extends IdoQuery
public function addFilter(Filter $filter) public function addFilter(Filter $filter)
{ {
$strangers = array_diff(
$filter->listFilteredColumns(),
array_keys($this->columnMap['contacts'])
);
if (! empty($strangers)) {
$this->transformToUnion();
}
foreach ($this->subQueries as $sub) { foreach ($this->subQueries as $sub) {
$sub->applyFilter(clone $filter); $sub->applyFilter(clone $filter);
} }
@ -67,21 +75,15 @@ class ContactQuery extends IdoQuery
protected function joinBaseTables() protected function joinBaseTables()
{ {
$this->contactQuery = $this->db->select(); $this->contactQuery = $this->createSubQuery('Hostcontact', array_keys($this->columnMap['contacts']));
$this->contactQuery->setIsSubQuery();
$this->subQueries[] = $this->contactQuery;
$this->select->distinct()->from( $this->select->from(
['c' => $this->contactQuery], ['c' => $this->contactQuery],
[] []
); );
$hosts = $this->createSubQuery('hostcontact', array_keys($this->columnMap['contacts']));
$this->subQueries[] = $hosts;
$this->contactQuery->union([$hosts], Zend_Db_Select::SQL_UNION_ALL);
$services = $this->createSubQuery('servicecontact', array_keys($this->columnMap['contacts']));
$this->subQueries[] = $services;
$this->contactQuery->union([$services], Zend_Db_Select::SQL_UNION_ALL);
$this->joinedVirtualTables['contacts'] = true; $this->joinedVirtualTables['contacts'] = true;
} }
@ -103,4 +105,24 @@ class ContactQuery extends IdoQuery
return $this; return $this;
} }
public function transformToUnion()
{
$this->contactQuery = $this->db->select();
$this->select->reset();
$this->subQueries = [];
$this->select->distinct()->from(
['c' => $this->contactQuery],
[]
);
$hosts = $this->createSubQuery('Hostcontact', array_keys($this->columnMap['contacts']));
$this->subQueries[] = $hosts;
$this->contactQuery->union([$hosts], Zend_Db_Select::SQL_UNION_ALL);
$services = $this->createSubQuery('Servicecontact', array_keys($this->columnMap['contacts']));
$this->subQueries[] = $services;
$this->contactQuery->union([$services], Zend_Db_Select::SQL_UNION_ALL);
}
} }

View File

@ -85,22 +85,7 @@ class HostcontactQuery extends IdoQuery
[] []
); );
$this->select->joinLeft( $this->joinedVirtualTables = array('contacts' => true);
['hc' => $this->prefix . 'host_contacts'],
'hc.contact_object_id = c.contact_object_id',
[]
)->joinLeft(
['h' => $this->prefix . 'hosts'],
'h.host_id = hc.host_id',
[]
)->joinLeft(
['ho' => $this->prefix . 'objects'],
'ho.object_id = h.host_object_id AND ho.is_active = 1',
[]
);
$this->joinedVirtualTables['contacts'] = true;
$this->joinedVirtualTables['hosts'] = true;
} }
/** /**
@ -143,6 +128,26 @@ class HostcontactQuery extends IdoQuery
); );
} }
/**
* Join hosts
*/
protected function joinHosts()
{
$this->select->joinLeft(
['hc' => $this->prefix . 'host_contacts'],
'hc.contact_object_id = c.contact_object_id',
[]
)->joinLeft(
['h' => $this->prefix . 'hosts'],
'h.host_id = hc.host_id',
[]
)->joinLeft(
['ho' => $this->prefix . 'objects'],
'ho.object_id = h.host_object_id AND ho.is_active = 1',
[]
);
}
/** /**
* Join instances * Join instances
*/ */