Nullwerte in anderer Tabelle suchen

Nullwerte in anderer Tabelle suchen

am 29.08.2007 23:03:56 von Markus Schmidt

Hallo NG! Habe hier folgendes kleines Problemchen:

Tabelle 1: Adressen
Tabelle 2: Angebote

Die Tabelle Angebote enthält Adressen.ID und Leistungen.ID und ich würde
gerne herausfinden, zu welcher Adresse es KEINE Leistungen gibt. Folgendes
funktioniert zwar, ist aber relativ langsam...

Zur Info: Tabelle Adressen ca. 3500 Einträge, Tabelle Leistungen ca. 4000,
pro Adresse sind bis zu 30 Leistungen möglich. Hier meine Query:

SELECT
users.username, adressen.anrede, adressen.vorname, adressen.nachname,
adressen.email, count( listing.therapeut ) AS listings,
CONCAT(adressen.vorname,' ',adressen.nachname) AS fullname
FROM
adressen
LEFT OUTER JOIN
listing ON ( adressen.uid = listing.therapeut )
INNER JOIN
users on users.uid = adressen.uid
GROUP BY
adressen.uid
ORDER BY
listings asc


in der schleife gibt es dann die abfrage ob $row["listings"]=="0" ist ; wenn
ja wird der PHPMailer angeworfen, eine Mail generiert und zum nächsten
Datensatz... Nun ist das Ganze aber wohl so komplex (gross) geworden, das
das Script nicht mehr durchläuft, sondern nach 30 Sekunden abbricht :(

Jetzt meine Frage(n):

1. Wie baue ich in die Query ein, das NUR datensätze angezeigt werden, bei
denen listings = '0' ist (where listing='0' bringt fehler "spalte kenn ich
nicht" und where count( leistungen.adress_ID)='0' bringt einen illegalen mix
von groups.

2. Hat jemand eine Idee, wie das besser (schneller) zu machen ist? Dieses
Script läuft zwar nur einmal pro woche als Reminder aber evtl. ist da ja
etwas tuning rauszuholen.

1000dank im Voraus
Markus

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 00:16:42 von Claus Reibenstein

Markus Schmidt schrieb:

> [...] Nun ist das Ganze aber wohl so komplex (gross) geworden, das
> das Script nicht mehr durchläuft, sondern nach 30 Sekunden abbricht :(
>
> 2. [...] Dieses
> Script läuft zwar nur einmal pro woche als Reminder aber evtl. ist da ja
> etwas tuning rauszuholen.

Unter diesen Umständen würde es eigentlich genügen, die maximale
Ausführungszeit für dieses Script hochzusetzen. Oder lässt Dein Provider
das nicht zu?

Gruß. Claus

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 00:28:45 von Markus Schmidt

> Unter diesen Umständen würde es eigentlich genügen, die maximale
> Ausführungszeit für dieses Script hochzusetzen. Oder lässt Dein Provider
> das nicht zu?
>
> Gruß. Claus

Hallo Claus,
danke für die Antwort! Doch - der lässt das schon zu, da der Server meiner
ist. Das Ausführungslimit hab ich schon auf 10 Minuten hochgedreht, jetzt
klappt das auch - aber so ganz kann das ja nicht der Sinn der Sache sein -
es soll ja nicht bei den derzeitigen Einträgen bleiben, sondern mehr
werden... Und meine Lust, die max_execution_time irgendwann auf 3 Tage zu
stellen hält sich dann doch etwas in Grenzen ;-)

Gruß
Markus

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 00:48:06 von Claus Reibenstein

Markus Schmidt schrieb:

>> Unter diesen Umständen würde es eigentlich genügen, die maximale
>> Ausführungszeit für dieses Script hochzusetzen. Oder lässt Dein Provider
>> das nicht zu?
>
> danke für die Antwort! Doch - der lässt das schon zu, da der Server meiner
> ist. Das Ausführungslimit hab ich schon auf 10 Minuten hochgedreht, jetzt
> klappt das auch - aber so ganz kann das ja nicht der Sinn der Sache sein -

Warum nicht? Ich habe auch einzelne Scripte, die etwas länger brauchen
als andere, an denen aber nicht mehr viel zu optimieren ist und die
dafür auch zu selten laufen müssen. In diesen Scripten setze ich die
Zeit einfach hoch. Dafür ist dieser Parameter schließlich da.

> es soll ja nicht bei den derzeitigen Einträgen bleiben, sondern mehr
> werden... Und meine Lust, die max_execution_time irgendwann auf 3 Tage zu
> stellen hält sich dann doch etwas in Grenzen ;-)

Wenn Dein Script tatsächlich mal diese Größenordnung erreichen sollte,
wäre es an der Zeit, doch mal über ein bisschen Optimierung
nachzudenken. Bis dahin gibt es aber auch wieder neue, schnellere
Hardware ;-)

Gruß. Claus

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 02:31:04 von B.Steinbrink

On Wed, 29 Aug 2007 23:03:56 +0200, Markus Schmidt wrote:

> Hallo NG! Habe hier folgendes kleines Problemchen:
>
> Tabelle 1: Adressen
> Tabelle 2: Angebote
>
> Die Tabelle Angebote enthält Adressen.ID und Leistungen.ID und ich würde
> gerne herausfinden, zu welcher Adresse es KEINE Leistungen gibt.
> Folgendes funktioniert zwar, ist aber relativ langsam...
>
> Zur Info: Tabelle Adressen ca. 3500 Einträge, Tabelle Leistungen ca.
> 4000, pro Adresse sind bis zu 30 Leistungen möglich. Hier meine Query:
>
> SELECT
> users.username, adressen.anrede, adressen.vorname, adressen.nachname,
> adressen.email, count( listing.therapeut ) AS listings,
> CONCAT(adressen.vorname,' ',adressen.nachname) AS fullname
> FROM
> adressen
> LEFT OUTER JOIN
> listing ON ( adressen.uid = listing.therapeut )
> INNER JOIN
> users on users.uid = adressen.uid
> GROUP BY
> adressen.uid
> ORDER BY
> listings asc
>
>
'> 1. Wie baue ich in die Query ein, das NUR datensätze angezeigt werden,
> bei denen listings = '0' ist (where listing='0' bringt fehler "spalte
> kenn ich nicht" und where count( leistungen.adress_ID)='0' bringt einen
> illegalen mix von groups.

WHERE geht nicht, weil das keine Spalte ist, berechnete Werte kannst du
nur in HAVING angeben. Aber das filtert nur die Ausgabe, d.h. es spart
dir primär ein wenig Zeit auf Seiten des Programms, was die Resultatmenge
verarbeitet.

> 2. Hat jemand eine Idee, wie das besser (schneller) zu machen ist?
> Dieses Script läuft zwar nur einmal pro woche als Reminder aber evtl.
> ist da ja etwas tuning rauszuholen.

Was du suchst ist NOT EXISTS(...) oder ein LEFT JOIN bei dem du den
Primärschlüssel (oder irgendwas anderes, dass NOT NULL ist) auf NULL
testest.

Zum Bleistift:
SELECT
foo.*
FROM
foo
LEFT JOIN
bar ON bar.xxx = foo.yyy
WHERE
bar.pk IS NULL

"pk" soll dabei der Primärschlüssel vom bar sein. Der wird nur genau dann
NULL, wenn eben gerade keine passende Zeile in bar gefunden wurde (durch
die LEFT JOIN Semantik). Das optimiert MySQL dann auch soweit, dass es
nach der ersten gefundenen Zeile aufhört zu suchen (EXPLAIN sollte "Not
exists" oder so sagen), während dein COUNT(*) ja alle Zeilen benötigt.

Was in deinem Fall schneller ist, dass NOT EXISTS Subquery oder der LEFT
JOIN, musst du halt ausprobieren, um einen Table Scan der ersten Tabelle
kommst du wohl nicht herum, aber zumindest um das GROUP BY.

Björn

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 08:32:49 von Stefan+Usenet

On Thu, 30 Aug 2007 00:31:04 +0000 (UTC) Björn Steinbrink wrote:
> > 2. Hat jemand eine Idee, wie das besser (schneller) zu machen ist?

> SELECT
> foo.*
> FROM
> foo
> LEFT JOIN
> bar ON bar.xxx = foo.yyy
> WHERE
> bar.pk IS NULL

Das macht sowohl die Abfrage, als auch das Programm jedenfalls deutlich
einfacher und ist aus dieser Sicher sehr zu empfehlen. Ich glaube jedoch
_nicht_, dass die Ausfuehrung auf makroskopischer Ebene dadurch deutlich
schneller wird. Das mehrfache Versenden von Mails legt die (ebenfalls
mehrfache) Verwendung von mail() nahe, und je nach Konfiguration des
Hosts kann das ziemlich lange dauern. Schneller wird es vor allem dann,
wenn die Mails vom lokalen Mailer erst einmal in die Queue gestellt und
nicht gleich abgearbeitet werden - diese Konfiguration wird der OP aber
wohl nicht beeinflussen koennen.

Servus,
Stefan

--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich

Seeligkeit und Vergnügen. Mit Stefan. Ein antiquiertes Vergnügen!
(Sloganizer)

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 08:51:59 von Claus Reibenstein

Markus Schmidt schrieb:

> in der schleife gibt es dann die abfrage ob $row["listings"]=="0" ist ; wenn
> ja wird der PHPMailer angeworfen, eine Mail generiert und zum nächsten
> Datensatz...

Verstehe ich Dich richtig: Du generierst für jeden einzelnen Treffer
eine separate Mail? Warum das denn? Wäre es nicht sinnvoller, _eine_
Mail zu generieren für _alle_ Treffer?

Oder sollen das individualisierte Mails sein, also jede Mail an einen
anderen Adressaten mit anderem Inhalt?

Gruß. Claus

Re: Nullwerte in anderer Tabelle suchen

am 30.08.2007 09:05:05 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: Nullwerte in anderer Tabelle suchen

am 03.09.2007 20:25:27 von Markus Schmidt

>> Verstehe ich Dich richtig: Du generierst für jeden einzelnen Treffer
>> eine separate Mail? Warum das denn? Wäre es nicht sinnvoller, _eine_
>> Mail zu generieren für _alle_ Treffer?

Ja - richtig - bei jedem (!) Treffer wird eine Mail erzeugt - im Sinne von
"Sehr geehrt.. Anrede, Vorname, Nachname,
leider haben Sie noch nicht alle Felder blaah bitte klicken Sie auf
"personalisierter Link" um Ihre Einstellungen direkt zu bearbeiten blaah"

>
> Vielleicht sollte man als hilfreiches Stichwort noch 'BCC' nennen...

wird - weil siehe oben - nicht wirklich klappen

>
>>
>> Oder sollen das individualisierte Mails sein, also jede Mail an einen
>> anderen Adressaten mit anderem Inhalt?

Si! Wenn ich die Daten schon habe, kann ich die Leutchen ja auch beim Namen
ansprechen...

>
> Bei SPAM gibt man sich ja gewöhnlich da eher weniger Mühe.

.... und genau von denen will ich mich ja unterscheiden ;-)

Markus

Re: Nullwerte in anderer Tabelle suchen

am 03.09.2007 20:29:33 von Markus Schmidt

"Stefan Froehlich" schrieb im Newsbeitrag
news:1t46d663f0i2d5n3e9%sfroehli@Froehlich.Priv.at...

[...]

> Das macht sowohl die Abfrage, als auch das Programm jedenfalls deutlich
> einfacher und ist aus dieser Sicher sehr zu empfehlen. Ich glaube jedoch
> _nicht_, dass die Ausfuehrung auf makroskopischer Ebene dadurch deutlich
> schneller wird. Das mehrfache Versenden von Mails legt die (ebenfalls
> mehrfache) Verwendung von mail() nahe, und je nach Konfiguration des
> Hosts kann das ziemlich lange dauern. Schneller wird es vor allem dann,
> wenn die Mails vom lokalen Mailer erst einmal in die Queue gestellt und
> nicht gleich abgearbeitet werden - diese Konfiguration wird der OP aber
> wohl nicht beeinflussen koennen.

Hi Stefan,
der Ansatz war prima! Danke - der Timeout ist damit erledigt. In Verbindung
mit deiner anderen Idee geht das jetzt ab wie "Schmidts Katze". Nochmal
Danke.

Hab einfach einen 2. Javamailer draufgepflanzt, der ausschliesslich für
diese Reminder (und die anderen die da so laufen) zuständig ist; normales
Mail mach weiterhin Qmail. Dieser Mailer nimmt die mails an, und stopft sie
in eine Warteschlange, die dann abgearbeitet wird, wenn das Script ein "ich
habe fertig" sendet...

Läuft super..

Vielen Dank an alle!