I have a query that gets me a Geo-Structure from the database.
Categories Table (30.000 rows inside):
id title parent type
-------------------------------
1 germany 0 1
2 bavaria 1 2
3 upper bavaria 2 3
4 munich 3 4
6 italy 0 1
7 toscana 6 2
8 city florence 7 3
9 florence 8 4
Categories Language Table
cid language title
--------------------------
1 en-UK germany
2 de-DE deutschland
Objects table:
id title landid regionid uregionid cityid
--------------------------------------------------
1 o1 1 2 3 4
2 o2 1 2 3 4
3 o3 6 7 8 9
MySQL query:
SELECT c.id, c.title, l.title AS translated, c.type, c.parent, count(c.id) as cnt
FROM category c
LEFT JOIN objects o ON (o.landid = c.id OR o.regionid = c.id OR o.uregionid = c.id OR o.cityid = c.id)
LEFT JOIN category_lang l ON l.cid = c.id AND l.language = "en-UK"
WHERE c.published = 1 AND o.published = 1
GROUP BY c.id
ORDER BY c.parent
I get an associative array ($tree) with values like here:
Array
(
[0] => Array
(
[id] => 1
[title] => Germany
[type] => 1
[parent] => 0
[cnt] => 1
)
[1] => Array
(
[id] => 6
[title] => Italy
[type] => 1
[parent] => 0
[cnt] => 1
)
[2] => Array
(
[id] => 2
[title] => Bavaria
[type] => 2
[parent] => 1
[cnt] => 1
)
[3] => Array
(
[id] => 7
[title] => Toscana
[type] => 2
[parent] => 6
[cnt] => 1
)
[4] => Array
(
[id] => 3
[title] => Upper Bavaria
[type] => 3
[parent] => 2
[cnt] => 1
)
[5] => Array
(
[id] => 8
[title] => City Florence
[type] => 3
[parent] => 7
[cnt] => 1
)
[6] => Array
(
[id] => 4
[title] => Munich
[type] => 4
[parent] => 3
[cnt] => 1
)
[7] => Array
(
[id] => 9
[title] => Florence
[type] => 4
[parent] => 8
[cnt] => 1
)
)
Then i create a structure that will prepare the display of a select list:
public static function buildTree($tree, $root = 0) {
$return = array();
foreach($tree as $child) {
if($child['parent'] == $root) {
$return[] = array(
'name' => $child,
'next' => self::buildTree($tree, $child['id'])
);
}
}
return empty($return) ? null : $return;
}
Then i send the structure inside $return to a function to create the final select list:
public static function buildSelect($tree, $s) {
$option = '';
if(!is_null($tree) && count($tree) > 0) {
foreach($tree as $node) {
$selected = '';
$class_type = $node['name']['type'];
$option .= '<option value="'.$node['name']['id'].'" class="h'.$class_type.'" '.$selected.' data-type="'.$node['name']['type'].'">'
.$node['name']['title']. ' (' . $node['name']['cnt'] . ')</option>'
. self::buildSelect($node['next'], $s);
}
return $option;
}
}
This all works but if the Geo-Structure gets really big the db query gets terrible slow. Would appreciate any ideas about how to speed this up, thanks!