Velka „prasárna“ ve výběru dat z DB
- wicked
- Člen | 290
Ahoj kluci,
mám takový dotaz, je tohle hodně velká „prasárna“ na dotazy do DB??? (podle mě jo)
Vemte, že se může vytáhnout třeba 1 000 000 adres …
A dále ještě … asi jsem mimoň, ale proč mě to zase pošle jenom na první adresu nalezenou? Myslel jsem, že když je to ve foreach, pošle to na všechny …
Děkuji
protected function execute(InputInterface $input, OutputInterface $output) {
try {
// Nastaveni modelu
$cron = $this->cron->findAll();
$emailySeznamy = $this->emailySeznamy->findAll();
$emaily = $this->emaily->findAll();
$kampane = $this->kampane->findAll();
$seznam = $this->seznamy->findAll();
// Nastaveni datetime
$datetime = new Nette\Utils\DateTime();
// Projeti cronu
foreach ($cron as $c) {
if ($c->start->format('Y-m-d H:i') === $datetime->format('Y-m-d H:i')) {
foreach ($seznam->where('id', $c->seznamy_id) as $s) {
foreach ($emailySeznamy->where('seznamy_id', $s->id) as $es) {
foreach ($emaily->where('id', $es->emaily_id) as $e) {
try {
$mail = new Message();
$mail->setFrom('info@jirickajakub.cz');
$mail->addTo($e->email);
$mail->setSubject('Pokus cron emailu');
$mail->setBody('ANO! :) <br> cas:' . $e->email . $datetime . 'cron id:' . $c->id . 'cron cas:' . $c->start);
$mailer = new Nette\Mail\SendmailMailer();
$mailer->send($mail);
sleep(1);
} catch (Nette\Mail\SmtpException $ex) {
Debugger::log($ex, Debugger::ERROR);
throw $ex;
}
}
}
}
}
}
$output->writeLn(new Nette\Utils\DateTime() . '<info>[OK] - cron</info>');
return 0;
} catch (\Exception $exc) {
$output->writeLn(new Nette\Utils\DateTime() . '<error>cron - ' . $exc->getMessage() . '</error>');
return 1;
}
}
- Filip Klimeš
- Nette Blogger | 156
Já osobně bych místo foreachování vybral data nějakým joinem a iteroval už pouze přes ty maily. Tedy postavit dotaz cca jako:
SELECT emaily.email, crony.id, crony.start, ... FROM crony
INNER JOIN seznamy ON seznamy.id = crony.seznamy_id
INNER JOIN emailySeznamy ON emailySeznamy.seznamy_id = seznamy.id
INNER JOIN emaily ON emaily.id = emailySeznamy.emaily_id
WHERE crony.start LIKE :datum
a pak už jen:
$now = new DateTime();
$emaily = $this->emaily->findByCronStart($now);
foreach($emaily as $email) {
...
}
Editoval Filip Klimeš (2. 3. 2015 19:14)
- wicked
- Člen | 290
Tak jsem to nějak zkusil …
Udělal jsem si toto v modelu:
public function runCron($datum) {
return $this->database->query('SELECT emaily.*, cron.*, cron.*, kampane.* FROM cron
INNER JOIN seznamy ON seznamy.id = cron.seznamy_id
INNER JOIN emaily_seznamy ON emaily_seznamy.seznamy_id = seznamy.id
INNER JOIN emaily ON emaily.id = emaily_seznamy.emaily_id
INNER JOIN kampane ON kampane.id = cron.kampane_id where cron.start LIKE ?', $datum);
}
V presenteru jednoduchy dump:
kde cas odpovida zaznamu v DB …
public function beforeRender() {
$cron = $this->cron->runCron('2015-03-02 18:56:00');
dump($cron);
}
Coz me vygeneruje takovyto SQL dotaz (debugg bar)
SELECT emaily.*, cron.*, cron.*, kampane.*
FROM cron
INNER JOIN seznamy ON seznamy.id = cron.seznamy_id
INNER JOIN emaily_seznamy ON emaily_seznamy.seznamy_id = seznamy.id
INNER JOIN emaily ON emaily.id = emaily_seznamy.emaily_id
INNER JOIN kampane ON kampane.id = cron.kampane_id
where cron.start LIKE '2015-03-02 18:56:00'
Ale v dumpu mám:
Nette\Database\ResultSet #9f3d
connection private => Nette\Database\Connection #bd57
supplementalDriver private => Nette\Database\Drivers\MySqlDriver #9e47
connection private => Nette\Database\Connection #bd57
pdoStatement private => PDOStatement #65b1
queryString => "SELECT emaily.*, cron.*, cron.*, kampane.* FROM cron
INNER JOIN seznamy ON seznamy.id = cron.seznamy_id
INNER JOIN emaily_seznamy ON emaily_seznamy. ... " (329)
result private => NULL
resultKey private => -1
results private => NULL
time private => 0.00014615058898926
queryString private => "SELECT emaily.*, cron.*, cron.*, kampane.* FROM cron
INNER JOIN seznamy ON seznamy.id = cron.seznamy_id
INNER JOIN emaily_seznamy ON emaily_seznamy. ... " (329)
params private => array ()
types private => NULL
Takže žádné data … (Nebo jsem slepý?)
Když to projedu forach, tak to na mě řve:
Found duplicate columns in database result set
Nápad/rada?
- studna
- Člen | 181
Ta hláška Found duplicate columns in database result set
přesně říká, co je špatně. Nepoužívej „hvězdičku“, ale vyber
pouze sloupce, které opravdu potřebuješ. A pokud potřebuješ vybrat více
stejnojmenných sloupců, tak si je aliasuj.
$db->query('SELECT emaily.id, cron.id cron_id, ...');
Editoval studna (7. 3. 2015 16:10)