Hallo,
andreas@a-kretschmer.de schrieb:
Zitat von Thomas Schmidt schmidt@netaction.de:
Zweites kostet es 25% CPU, wenn ich jede Sekunde das SELECT count(*) ausführe. Egal, ob sich an der Tabelle überhaupt etwas ändert. Diesen
Ich nix MySQL, aber unter PG würde dies auch dauern, da es einen Seq-Scan erfordert.
Eigentlich sollte es auch ein Full-Scan ueber einen Index tun, in dem nachweislich alle interessierenden Datensaetze enthalten sind (z.B. PK-Index). Ist natuerlich eine Frage der Spitzfindigkeit des Optimizers.
Normalerweise braucht man dies nicht, also die exakte Anzahl. Oft reicht eine grobe Schätzung der Gesamtanzahl, sie gilt ja streng genommen auch nur für die konkrete TX, in der Du das abfragst. Also, entweder guggst Du in den Statistiken nach einer Schätzung (in PG wäre dies pg_class.reltuples),
die Statistik halbwegs aktuell zu halten, kostet ein ANALYZE und damit fast einen Full Scan (je nach Genauigkeit).
oder aber führst über einen TRIGGER einen exakten Counter.
TRIGGER: Bei sowas also Trigger auf INSERT und DELETE. Man muss sich dann dessen bewusst sein, dass man Redundanzen schafft, die einem in manchen Faellen wieder auf die Fuesse fallen.
Die einfache Implementierung zaehlt in einem Datensatz in einer getrennten Tabelle mit, es gibt dann bei jedem INSERT/DELETE eine Sperre auf diesen Datensatz. Solange keine parallellaufenden Aktionen auf der urspruenglichen Tabelle ausgeloest werden, hat man als Performanceeinbusse nur die Ausfuehrung vom Trigger und das Update (Satz finden, Datensatz aendern, Transaktionslog schreiben).
Bei mehreren konkurrierenden Transaktionen hat man da eine u.U. ekelhafte Serialisierung erzeugt.
@Thomas: Wann und wo brauchst Du die Anzahl der Datensaetze in der Tabelle? Fuer den Fall, dass Du das im selben Prozess wie das INSERT brauchst, kannst Du am Anfang das SELECT count(*) machen und dann die datensatzerzeugende Anwendung eigenstaendig die INSERTs zaehlen lassen - das stimmt solange wie keine anderen Transaktionen INSERT oder DELETE ausfuehren.
Holger