Cachování Doctrine, proměnných a další typy na zrychlení

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

Zdravím,
snažím se zrychlit načítání stránke a proto bych rád zavedl cache:

  • Pro kdyby/doctrine – našel jsem kdyby/DoctrineCache, ale bohužel neobsahuje dokumentaci a tak nevím, jak správně použít
  • Dále bych rád cachoval různé výstupy funkcí. Například funkce, která vyhodí přezdívku uživatele podle jeho ID apod., jak na to?

Pokud máte ještě nějaké typy jak zrychlit web, co by šlo ještě cachovat apod., buu jen rád.

Azathoth
Člen | 495
+
+1
-

výstupy různých složitých doctrine query cacheuji úplně obyčejně, pomocí nette cache. Například, cachuješ přezdívku podle id. Tak si tu pžezdívku ulož do cache pod klíčem ‚nickname‘.$id a je to…
a doporučuji zkusit optimalizovat dotazy. Kde nepotřebuješ celou entitu, ale jen něco, tak si vytahuje jen to, co potřebuješ. Co lze udělat v databázi, tak udělej v dql a ne v php.
Dej pozor na 1+n problém a jestli se ti někde hodí extraLazy associations, tak ty by to taky mohly možná zrychlit, ale to záleží na tvém use case.
Jestli chceš cacheovat entity z doctrine, tak se vykašli na kdyby/doctrineCache, to je jen na metadata, dotazy atd…a použij z Doctrine 2.5 (je v @dev kdyby/doctrine) L2 cache

taky by možná stálo za to cacheovat celé kusy latte šablon (typicky, jestli máš komponentu se seznamem akcí, kterou vypisuješ pořád, ale nové akce někdo přidává jednou za 3 dny, je lepší to cacheovat v latte).
Prostě doporučuji si projít dokuzmentaci ke cache a přitom přemýšlet, kde to můžeš použít. KDyž jsem s nette začal, tak jsem tui kapitolu jen prolétl a když jsem pak potřeboval zrychlovat, tak mi pomohlo si to přečíst znovu.

A pokud někde potřebuješ doctrine data jen na výpis, možná se vyplatí array hydratace místo klasického nasypání do objektů, protože plnění objektů z databáze přes reflexi je poměrně pomalé.

Taky si dej pozor, pokud děláš v dql hodně joinů, to taky zpomaluje a jsou způsoby jak to optimalizovat.
Ale jinak se ptáš strašně obecně a bylo by lepší si pustit profiler, zjistit slabá místa a pak tu rozebírat konkrétní problémy.

Editoval Azathoth (20. 8. 2015 20:37)

Tomáš Votruba
Moderator | 1114
+
+1
-

Ahoj, mrkni na Awesome Doctrine, dej hledat „performance“ – je tam pár článků, které se ti můžou hodit.

Editoval Tomáš Votruba (20. 8. 2015 21:29)

Lukeluha
Člen | 130
+
0
-

My teda používáme Kdyby\Doctrine společně s Kdyby\Redis a rychlost je super :)

Do Redisu si Doctrine ukládá mapování + navíc jej můžeš využít pro své cachování samotných výsledků.

Editoval Lukeluha (20. 8. 2015 22:30)

Azathoth
Člen | 495
+
0
-

@Lukeluha jak se cache v Kdyby/Redis výkonově a časově liší od nette cache s fileStorage?

Lukeluha
Člen | 130
+
0
-

@Azathoth No třeba v tom že FileStorage je ukládání na disk, kdežto Redis ukládá do paměti – tím pádem rychlost se snad ani nedá porovnávat :)

Editoval Lukeluha (21. 8. 2015 9:00)

David Matějka
Moderator | 6445
+
0
-

k rychlosti – http://www.slideshare.net/…/kdyby-redis slide 16 a dal

pro doctrinu na metadata je asi nejrychlejsi apcu :)

Filip Procházka
Moderator | 4668
+
+1
-

Prod doctrine metadata (a query cache) rozhodně APCu. Pro data redis úplně v pohodě, klidně ho tam šoupnout napřímo bez zámků.

redis:
	versionCheck: off
	storage: on
	lockDuration: 30
	connectionAttempts: 3
	session: {native: off, lockAcquireTimeout: 10}

	clients:
		doctrine < default:
			database: 6
			debugger: off

doctrine:
	resultCache: redis(@redis.doctrine_client::getDriver())

Pokud potřebuješ zámky, tak

doctrine:
	resultCache: default

což použije IStorage z Nette, který Kdyby\Redis nahradí za svou implementaci a budeš to mít včetně zámků. Jen pro doplnění, my to na produkci máme bez zámků :)


Nad Kdyby/DoctrineCache vůbec nepřemýšlej, je to jenom bridge mezi Doctrine a Nette ⇒ vůbec tě nezajímá.

Nastuduj si ResultCache

$repository = $this->em->getRepository(Store::class);
$store = $repository
	->createQueryBuilder('s')->addSelect('c', 'a')
	->leftJoin('s.country', 'c')
	->leftJoin('s.address', 'a')
	->andWhere('s.id = :storeId', $storeId)
	->getQuery()->useResultCache(TRUE, 60, 'store-' . $storeId)
	->getResult(); // výsledek se uloží do redisu na minutu

Second Level Cache, která je implementovaná zatím pouze v Kdyby\Doctrine v masteru. To už je trošku složitější na použití.