Table Selection – pomalé accessColumn

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

Snažil jsem se z databáze načíst víc řádků a u hranice kolem 10000 řádků se začala výrazně projevovat exponenciální časová náročnost. Přes profiler jsem zjistil, že za to může metoda Selection->accessColumn. Pokud načtu 1000 řádků, trvá 0.2ms. Pokud načtu 5000 řádků, trvá 1ms (tedy 5000ms dohromady).
Platí to pro Nette 2.3.9. Podle mě za to může následující foreach, ale nepodařilo se mi zjistit k čemu slouží a jestli se dá nějak odstranit/obejít:

<?php
foreach ((array) $this->rows as $row) {
	$primary = $row->getPrimary();
	$primaryValues[] = is_array($primary) ? array_values($primary) : $primary;
}
?>

Tušíte někdo?

CZechBoY
Člen | 3608
+
0
-

Jakou metodou získáváš řádky? Bereš data z jedný tabulky nebo z víc?

Martin Tomec
Člen | 2
+
0
-

Data jsou z více tabulek, tahám jen sloupce co potřebuji přes

$table->select("$dbColumn AS $variable");

Odzkoušel jsem 2 metody. První metoda volá accessColumn 1× pro každý řádek a accessColumn se zpomaluje (pro více řádků v resultu):

while ($row =  $table->fetch()) {
	foreach ($row AS $value) {
		$dummy .= $value;
	}
}

Druhá metoda volá accessColumn víckrát (dle počtu sloupců) ale samotné accessColumn se nezpomaluje, takže to jde použít jako workaround:

while ($row =  $table->fetch()) {
	$dummy .= $row["column1"];
	$dummy .= $row["column2"];
	...
}
CZechBoY
Člen | 3608
+
0
-

Pokud to rovnou nevypisuješ tak si to asi můžeš i nechat nafetchovat (fetchAll/fetchAssoc) všechno najednou.

Unlink
Člen | 298
+
0
-

@CZechBoY Ono sa to interne tak či tak fetchne naraz.
@MartinTomec pokiaľ manuálne nastavíš stĺpce, ktoré sa z DB načítajú, tak ten foreach ktorý ukazuješ sa nevykonáva, jediný dôvod tvojho problému bude asi toto
https://github.com/…election.php#L726

Skús tento riadok kódu zakomentoval a daj vedieť či to už nerobí problém, ak to problém vyrieši, tak môžeš poslať PR kde túto časť presunieš až do toho ďalšieho ifu.