stovky tisíc insertů v mysql

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

Zdravím potýkám se s problémem. Přes nette a dibi provádím převod databáze z sqlite do mysql, některé tabulky mají až stovky tisíc záznamů a u nich mi to vždy zatuhne. Snažím se rozdělit na několik dotazů ale hodí mi laděnka error

<?php
Fatal Error

Maximum execution time of 60 seconds exceeded

Source file ▼

File: D:\dev\www\lite\libs\dibi\libs\DibiResult.php   Line: 283

Line 276:            $this->seek((int) $offset);
Line 277:            $row = $this->fetch();
Line 278:            if (!$row) return array();  // empty result set
Line 279:
Line 280:            $data = array();
Line 281:            do {
Line 282:                if ($limit === 0) break;
Line 283:                $limit--;
Line 284:                $data[] = $row;
Line 285:            } while ($row = $this->fetch());
Line 286:
Line 287:            return $data;
Line 288:        }
Line 289:
Line 290:
?>

skript vypada takto:

<?php
		$this->template->tables = $this->dbs->getDatabaseInfo()->getTableNames();

		foreach($this->template->tables as $t)
		{

			$n = $this->dbs->query('SELECT Count(*) FROM %s',$t)->fetchSingle();

			$po = 100000;
				for($i = 0; $i <= $n; $i+=$po)
				{
					$offset=$po;
					$base = $i;
					$rowset = $this->dbs->query('SELECT * FROM %s LIMIT %i,%i',$t,$base,$offset)->fetchAll();

					foreach($rowset as $k=>$v)
						$this->dbm->insert($t,$v)->execute();
				}



		}
?>

Editoval pjoter (14. 2. 2010 14:15)

Honza Marek
Člen | 1664
+
0
-

Provádíš to na hostingu nebo u sebe na počítači? Ten limit se dá zvýšit, ale na hostinzích to bývá zakázané.

pjoter
Člen | 118
+
0
-

na localhostu pouzil jsem
<?php set_time_limit(0); ?>
a zatím to běží tak uvidíme

iguana007
Člen | 970
+
0
-

myslim, ze pokud to spustis z konzole a ne z browseru, tak tam se na timelimit nehraje … ale nejsem si 100% jisty, ale zkusit to muzes.

Vyki
Člen | 388
+
0
-

Jak píše Iguana, mrkni na použití CLI routeru z Nette.
EDIT\\ zde se o tom píše podrobněji

Editoval Vyki (13. 2. 2010 21:53)

toka
Člen | 253
+
0
-

A nebylo by jednodušší toto?

timbulko
Člen | 85
+
0
-

Prečo pri toľkých insertoch nepoužívaš transakcie? Prípadne Lock/Unlock ak používaš MyIsam.

pjoter
Člen | 118
+
0
-

poraď jak/proč bude to rychlejší?

Panda
Člen | 569
+
0
-

Pokud používáš INNODB, tak se pro každý INSERT mimo transakci (což je i případ, kdy transakce nepoužíváš) transakce spustí a pak commitne. Vkládání záznamů pak vypadá takto:

START TRANSACTION
INSERT ...
COMMIT

START TRANSACTION
INSERT ...
COMMIT

START TRANSACTION
INSERT ...
COMMIT

Při uzavření všeho do transakce by to vypadalo takto:

START TRANSACTION
INSERT ...
INSERT ...
INSERT ...
COMMIT

Nárůst výkonu se u mnoha insertů pohybuje v řádu tisíců procent.

LOCK by žádný vliv na výkon neměl mít, ale vkládání je pak bezpečnější (máš jistotu, že Ti do vkládaných dat nikdo nebude zasahovat).

timbulko
Člen | 85
+
0
-

Panda napsal(a):
LOCK by žádný vliv na výkon neměl mít, ale vkládání je pak bezpečnější (máš jistotu, že Ti do vkládaných dat nikdo nebude zasahovat).

Podľa testu, ktorý robil Jakub Vrána má aj LOCK v MyIsam minimálny efekt (cca. 8%) na rýchlosť pridávania. Viz. http://php.vrana.cz/…-tabulek.php – v prípade MyIsam by však bol pri veľkom množstve insertov najvýhodnejší tretí spôsob (ten je asi 20× rýchlejší)