Jednoduché snížení počtu dotazů na databázi

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Oli
Člen | 1215
+
0
-

Zdravím,
chtěl bych se zeptat jestli jde nějak jednoduše (bez kešování) snížit počet dotazů na databázi? Mám to takhle:

$menu = $this->connection->table($this->table)->where(/*podmínka*/);

// Tady nechápu, proč když dám $subMenu = $menu, tak to projde jen jednou a zbytek vubec nevypíše?
$subMenu = $this->connection->table($this->table)->where(/*podmínka*/);

foreach ($menu as $parent)
{
	foreach ($subMenu as $child)
	{
		if ($parent->id == $child->parent_id)
		{
			dump($child->title);
		}
	}
}

Problém je, že se ten vnořenej foreach pokaždý ptá až do databáze. Myslel jsem, že jak je to jednou načtený, tak že to bude brát dotazy z toho Nette\Database\Table\Selectionu. Že si to uloží a nebude se ptát databáze.

Někde jsem myslím kdysi četl, že když chci procházet výsledek z databáze vícekrát, že se na to používá nějak fetchAll(). Nevím jestli si to pamatuju dobře, nicméně mi to nefungovalo a ani nevím jestli by to pomohlo…

Díky

David Matějka
Moderator | 6445
+
0
-

opravdu to mas takhle? ze v tom vnorenem foreachy vzdycky vypisujes stejny submenu?

jinak, co mas za verzi nette?

Oli
Člen | 1215
+
0
-

Jo jo, mám to přesně takhle. Jen to je v šabloně a okolo je html. ;-)
Nette je 2.0.10.

Teda předpokládám, že to šahá pokaždé do db. Když totiž vypustím ten vnitřní foreach, tak padne počet dotazů o $child->title dolů. Ideálně bych použil jednu proměnnou a procházel to takhle:

foreach ($menu as $parent)
{
    foreach ($menu as $child)
    {
        if ($parent->id == $child->parent_id)
        {
            dump($child->title);
        }
    }
}

Ale, to ten child provede jen jednou.

David Matějka
Moderator | 6445
+
0
-

radsi napis, ceho chces dosahnout, protoze ta podminka ` if ($parent->id == $child->parent_id)` nepekne zavani :) + ukaz strukturu db

Oli
Člen | 1215
+
0
-

Z toho jsem měl strach :-D
V db mám zjednodušeně:

id parent_id title slug text
1 NULL Nadpis nadpis bla bla
2 1 Podnadpis podnadpis haha
3 NULL Nadpis 2 nadpis-2 bla bla
4 3 Podnadpis 2 podnadpis-2 haha
5 1 Podnadpis 3 podnadpis-3 bla bla
6 NULL Nadpis 3 nadpis-3 haha

Výstup by měl být něco jako:

<ul class="primary_menu">
	<li class="parent"><a href="javascript:void(0)">Nadpis 1<i></i></a>
		<ul>
			<li><a href="#">Podnadpis 1 1</a></li>
			<li><a href="#">Podnadpis 1 2</a></li>
		</ul>
	</li>
	<li class="parent"><a href="javascript:void(0)">Nadpis 2<i></i></a>
		<ul>
			<li><a href="#">Podnadpis 2 1</a></li>
			<li><a href="#">Podnadpis 2 2</a></li>
			<li><a href="#">Podnadpis 2 3</a></li>
		</ul>
	</li>
	<li><a class="single-line" href="#">Nadpis 3</a></li>
	<li><a href="#">Agisoft<br>Nadpis 4</a></li>
</ul>

Editoval Oli (11. 9. 2013 15:06)

David Matějka
Moderator | 6445
+
0
-

zkus:

$menu = $this->connection->table('menu')->where('parent_id IS NULL');

foreach($menu as $item) {

	foreach($item->related('menu') as $subItem) {

	}
}
Oli
Člen | 1215
+
0
-

Díky, nepomohlo to, naopak se to zhoršilo ;-) Moje řešení mělo 18 dotazů, tvoje 26. Vizuálně je výsledek stejný.

Pokud by si zapamatovalo nette ten dotaz, tak by bylo jen okolo 5 – 9 dotazu. Nevím přesně, který dotazy to ovlivňuje. Měl jsem 5 a/nebo 9 dotazů, když jsem oddělal vnitřní foreach.

Jiný nápad? :-)

EDIT: S related mám blbý zkušenosti co se týče počtu dotazů. Možná to používám blbě, ale vždycky mnohonásobně vzroste počet dotazů na db…

Editoval Oli (11. 9. 2013 15:31)

David Matějka
Moderator | 6445
+
0
-

muzes jeste poslat, jaky dotazy ti to vytvari?

ja to ted zkousel (mam teda 2.1) a zvladlo to ve 2 dotazech..

zkus kdyztak aktualizovat nette na novejsi verzi (2.0.12), jestli tam nebyl nejakej bug..

Oli
Člen | 1215
+
0
-

Ted jsem na to prisel. Delal to router. Omlouvam se za v podstatě ztrátu času. :-/ Uplně jsem zapomněl, že si předávám parent_id do odkazu a router, že to převádí… Id jsem změnil na slug, aby mě to nezapočítávalo dotazy pro router, ale na to parent_id jsem zapomnel :-/

Moje řešení má 7 dotazů, tvoje 8. Nevím, kde se tam ten jeden vzal, ale z něj už se nestřílí. Jsou to celkové dotazy na db, nejen na menu.

Díky!