Rychlost Nette\Database vs čisté PHP

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

Zdravím, mám jenom čistě technický dotaz týkající se rychlosti Nette\Database v2.1-dev vs čistého PHP (MySQLi).

Mám aplikaci psanou v Nette a pravidelně do ní nalévám nová data. Jedná se zhruba o 30k dotazů (vesměs INSERT / UPDATE). V čistém PHPku všechno proběhne zhruba za 3 – 5s, kdežto když jsem to teď přepsal pod Nette, tak to trvá okolo 100s.

Ano je mi jasný, že FW je pomalejší, ale že je to více než 10x? Mám se s tím prostě smířit a nechat teda loadovací skript v čistém PHP? Do Nette jsem to chtěl přepsat, aby to všechno bylo pod jednou střechou.

Díky.

Editoval Mysteria (29. 8. 2013 19:23)

Šaman
Člen | 2668
+
0
-

Počkej jestli se neozve Hrach, ten zná NDb jak své boty. Možná děláš něco nevhodně.
Používáš Nette\Database\Table, nebo čistě jen $connection->query(...)? Table může zdržovat. Máš správně kešování dotazů?

Ještě je varianta Dibi. Pokud ti jde o rychlost, tak také jen čisté $dibiConnection->query(), žádný fluent. Čisté MySQLi je hardcore, tomu bych se raději vyhnul. Ten desetinásobný propad výkonu určitě půjde nějak poladit.

Mysteria
Člen | 797
+
0
-

Všechny dotazy mám přes Nette\Database\Table, myslíš, že čisté query bude rychlejší?

Konkrétně taky mám čísla z posledních testů:

Database succesfully updated in 93.061649084091s with 19278 queries.

Editoval Mysteria (29. 8. 2013 20:43)

Šaman
Člen | 2668
+
0
-

Myslím, že čisté query bude rychlejší, u jednoho velkého projektu jsme to zkoušeli. U table byl brutální propad ve výkonu, ale to bylo před půl rokem a NDb se stále vyvíjí.

Mysteria
Člen | 797
+
0
-

Dobře zkusím to přepsat a dám vědět, zatím díky. :)

hrach
Člen | 1844
+
0
-

NDBT pouzivat tehdy, kdyz ma smysl – a ten je (zatim prevazne) pouze v selectech. INSERT a UPDATE urcite provadet jen pres NDB (bez T), kde je to temer ciste php, takze by to melo byt ok. NDB vs NDBT neni o tom, ze neco uz „neni“ cool. Napr. v NDBT se po insertu dela select…

Mysteria
Člen | 797
+
0
-

Tak po přepsání jsem se dostal na mnohem lepší čísla, která už jsou pro mě snesitelná, sice to je pořád zhruba 3× pomalejší, ale mnohem lepší než předtím.

Database succesfully updated in 15,84s with 25 308 queries.

Díky všem zúčastněným zapomoc.

Jan Mikeš
Člen | 771
+
0
-

Mozna by nam pomohlo vice, kdyby jsi ukazal jak to v NDB pises a jak to pises normalne – pak bychom ti mohli poradit presne pro tvuj konkretni pripad?

Editoval Lexi (30. 8. 2013 7:36)

Mysteria
Člen | 797
+
0
-

Tak konkrétní část kódu v Nette Database Table takto (v téhle části se provádí nejvíc dotazů):

if (isset($s->players_list) && is_array($s->players_list)) {
	foreach ($s->players_list as $p) {
		try {
			$sqlCount++;
			$db->table('sl_players_live')->insert(array(
				'sl_servers_live_id' => $serverId,
				'name' => $p->name,
				'time' => 5,
				'time_all' => 5,
				'online' => 1));
		} catch (\PDOException $e) {
			$sqlCount++;
			if ($e->errorInfo[1] === 1062) {
				$db->table('sl_players_live')->where('sl_servers_live_id = ? AND name = ?', $serverId, $p->name)->update(array(
					'time' => new SqlLiteral('time + 5'),
					'time_all' => new SqlLiteral('time_all + 5'),
					'online' => 1));
			}
		}
	}
}

A v čistém PHPku:

if (isset($s->players_list) && is_array($s->players_list)) {
	foreach ($s->players_list as $p) $i[] = $db->query("INSERT INTO sl_players_live (sl_servers_live_id, name, time, time_all, online) VALUES ($id, '$p->name', 5, 5, '1')
		ON DUPLICATE KEY UPDATE time = time + 5, time_all = time_all + 5, online = 1;");
}

Ono jsem pak ještě zjistil, že mezi čistým Query a Selection table není takovej rozdíl, že těch 90s vs 15s muselo být někde jinde (přetížený MySQL server nebo tak něco), protože nyní mi obě varianty trvají okolo 10 – 20s, což je sice 3× pomalejší než čistý PHPko, ale pro moje moje účely je to dostatečně krátká doba. Ale pokud máte čas, tak klidně klidně do toho, rád se přiučím od lepších. :)

hrach
Člen | 1844
+
0
-

No a hlavne je dost rozdil poustet dva dotazy s rezii na exception (velka), nebo jeden…

Jan Mikeš
Člen | 771
+
0
-

Muzes to udelat i pres 1 dotaz a ne pres 1000 viz mysql dokumentace

INSERT INTO table (a,b,c)
VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

Toto v NDB neudelas, muzes pouzit $db->query() nebo $db->exec() – alespon ja bych se ubral timto smerem, pokud ti jde o rychlost, pak urcite

Mysteria
Člen | 797
+
0
-

Sorry, že reaguji až tak pozdě, ale byl jsem na dovolené ;)

Lexi: Ano, tak jsem to taky zkoušel, ale 5s vs 15s mě už nezabije, takže to nechám takhle.

Díky všem za pomoc, můžeme to tady uzavřít.

Re4DeR
Člen | 71
+
0
-

no já takhle importoval asi 2000 záznamu a padalo mi to kdyz jsem importoval po jednom. zvladlo to asi 300 dotazu. multi insert pohoda :)