Performance

Ich habe folgendes Problem:

Datenbank angelegt. Ca. 1 Million Datensätze enthalten.

Select oder Update - Operationen laufen im (Milli-) Sekundenbereich ab.

So weit, so gut. Aber jetzt will ich eine Delete - Operation auf ca. 120.000 Sätze loslassen - soll dann ungefähr 5 Tage dauern?

Localhost, acht Prozessoren und 32 GB Hauptspeicher.

Was mache ich falsch?

Wie sieht die Tabelle und das DELETE-Statement aus? Wenn genutzt, was für ein Frontend setzt du für den DELETE ein?

Grüße

Jochen

ok, mal n schuss ins blaue

5 Tage für nen DELETE von ca. 120.000 Datensätzen riecht verdächtig nach nem problem im Datenbankdesign, nachfolgend eine unvollständige Auswahl möglicher Ursachen

a.) super-superextrem viele indices auf dieser Tabelle (und sogar dann käme mir das seeehr spanisch vor …)
b.) oder/und ner ganzen Horde von referenzierten und/oder referenzierenden Tabellen
c.) oder/und ein paar fehlende idices :slight_smile:
d.) oder/und löschst du Datensatz für Datensatz?

zu a.) Ich hab mal irgendwo gelesen, das bei extrem großen Datenmengen (1 Mio Datensätze ist nicht unbedingt extrem viel), empfohlen wurde, den ein oder anderen index zu droppen und nach dem DELETE neu zu erstellen. Das war allerdings vorn paar jahren, 7er Postgres, und würde auch nur dann was bringen, wenn du Datensatz für Datensatz löschst, da die indices IIRC nach jedem DELETE neu geschreiben werden.

→ Fazit: mehr infos needed

Nacht,

Jochen

Schon gelesen: Wir können nicht helfen wenn …?





mfg

fristo

Aus den Rückfragen - und dem zarten Hinweis von fristo - ersehe ich, dass ich mir das zu einfach vorgestellt habe. Tut mir leid, ich sammle halt noch erste Erfahrungen mit der pg…

Also, ich verwende auf einem MS 2003 AS eine pg 8.2 (läuft als Dienst) und den pg-Admin III. Die Datenbank enthält 12 Tabellen, die über eine JAVA - Anwendung (JBOSS / Hibernate) mit Einträgen gefüllt werden. Als Tool für das Debuggen läuft eine MyEclipse (6.0.1GA), von der aus auch JBOSS gestartet wird.

Diese Anwendung durchforstet einen inkonsistenten Datenbestand im File / Folder - System, kopiert ausgewählte Dateien um, macht einen Volltextindex, bildet einen Hash - Wert und schreibt diese Angaben (Quelle, Ziel, Ablageort des Volltextindexes, Hash, Dateityp, Qualifier, Größe, Besitzer, Rechteverwaltung) in die postgre. Die dazu genutzte Tabelle enthält einen zur Laufzeit vergebenen ein-eindeutigen Primärschlüssel, über den die Referenzen zusammengehalten werden.

Ein Job in der JAVA - Anwendungen ist in einen Fehler gelaufen, durch den zwar fleissig die Postgre mit Werten befüllt, aber keine Kopieraktionen mehr durchgeführt wurden. Bei einem bis dahin mit ca. 1,5 TerraByte gefüllten Datenbestand.

Da Quelle und Ziel nicht identisch sind, wenn die Quelle ein gezipptes Archiv war - wird ausgepackt und die Dateien werden einzeln in das Ziel kopiert - ist eine Verifikation im Datenbestand die “Suche nach der Stecknadel im Heuhaufen”. Ich habe mich dafür entschieden, den fraglichen Job (Fehler ist behoben) noch mal zu starten. Dazu will ich vorher die Postgre bereinigen.

Ich kann nicht ausschließen, das Indices etwas “abbekommen” haben. Deshalb habe ich den Index der pg neu aufgebaut, vorsichtshalber zusätzlich einen weiteren Lauf “VACUUM” durchgeführt. Und dann mit dem Statement

DELETE FROM tblfiles WHERE jobname = ‘JobName’

angestoßen. Lief am nächsten Morgen immer noch. Ich habe den Job abgebrochen und mit 100 Einträgen einen Test durchgeführt. Dieser hat etwas mehr als 11 Minuten gedauert. Der nächste Test - mit 150 Einträgen - entsprechend länger. Hochgerechnet auf den Gesamtbestand / Anzahl der zu löschenden Einträge bin ich auf 4,7 Tage Laufzeit gekommen.

Wie gesagt, alle anderen Kommandos auf die pg werden im Sekundenbereich abgearbeitet.

Ich hoffe, ich habe alle benötigten Angaben gemacht.

Grüße
W.K.

Doch noch etwas vergessen.

Ich habe die betreffenden Einträge auf einen ‘JobName’ gesetzt, der im weiteren Verfahren nicht mehr betrachtet wird - einschließlich der Abhängigkeiten. Das UPDATE lief ebenfalls in einem normalen Rahmen ab.

Aber ca. 120.000 möglicherweise korrupte Einträge stören mich dennoch.

Außerdem kann ich mir die - im Verhältnis zum Rest - exorbitante Dauer der DELETE - Statements nicht erklären.

Und so bin ich auch auf dieses Forum gestoßen - ich habe im Internet eine entsprechende Suche durchgeführt und bin dabei auf Treffer auf dieser Seite geleitet worden. Leider nicht auf eine Lösung für mein Problem.

Grüße
W.K.

das macht nix.

Also, ich verwende auf einem MS 2003 AS eine pg 8.2 (läuft als Dienst) und den pg-Admin III. Die Datenbank enthält 12 Tabellen, die über eine JAVA - Anwendung (JBOSS / Hibernate) mit Einträgen gefüllt werden. Als Tool für das Debuggen läuft eine MyEclipse (6.0.1GA), von der aus auch JBOSS gestartet wird.

Interessant wären Einstellungen der pg_hba.conf zur Speicherkonfiguration. Was man da an Gewinn rausholen kann, kannst Du im Blog vom Mastermind heute nachlesen.


Ich kann nicht ausschließen, das Indices etwas “abbekommen” haben. Deshalb habe ich den Index der pg neu aufgebaut, vorsichtshalber zusätzlich einen weiteren Lauf “VACUUM” durchgeführt. Und dann mit dem Statement

VACUUM ‘markiert’ tote Tupel, ‘VACUUM FULL’ löscht diese, ‘VACUUM FULL VERBOSE’ ist eine Quasselstrippe. Möglicherweise hast Du von diesen toten Dingern da jede Menge.

DELETE FROM tblfiles WHERE jobname = ‘JobName’

angestoßen. Lief am nächsten Morgen immer noch. Ich habe den Job abgebrochen und mit 100 Einträgen einen Test durchgeführt. Dieser hat etwas mehr als 11 Minuten gedauert. Der nächste Test - mit 150 Einträgen - entsprechend länger. Hochgerechnet auf den Gesamtbestand / Anzahl der zu löschenden Einträge bin ich auf 4,7 Tage Laufzeit gekommen.

Index auf jobname? Und für ein ‘explain analyse delete …’ mit 100 Einträgen war leider keine Zeit?

Btw.: Stringvergleiche sind teuer. Vielleicht solltest Du das Tabellendesign verändern. Und ja: ich bezweifle erheblich, daß PG mit 32 GByte RAM und 8 Zylindern auf allen Betrübssystemen gleich gut performt. Mehr sage ich jetzt mal nicht, sonst bekomme ich wieder Haue…

Andreas

Du Böser du, der Rechner allerdings - dies zur Ehrenrettung (geht sowas?) gewisser nicht näher bezeichneter ähhm Server-Betriebssysteme - scheint so oder so in der Lage (selbstverständlich nur meiner bescheidenen Meinung nach) eine etwas bessere Performance aufs Parkett zu legen.

100 Einträge in 11 Minuten, das macht 7 Sekunden pro Datensatz, das ist schon superextrem, egal was fürn BS.

Insofern → Datenbankdesign

Willste nicht mal die Tabellendefinition pasten, w.k.??

Na klar habe ich einen VACUUM - FULL gemacht.

Und was die Performance auf so einer im Prinzip potenten Maschine angeht: sauschlecht. Unter dem Betriebssystemaufsatz mit grafischer Oberfläche wird elend skaliert: eine CPU die rennt und der Rest pennt…

Erzeugt dann auch so ungefähr 13 - 15 % Last, aber was ist das schon, gemessen an den Möglichkeiten?

Der Hinweis auf die pg_hba_conf ist angekommen - ich habe die Installation mit den Standardwerten vorgenommen.

Heute habe ich die Anwendung (inklusive der Postgre) von einer Systemumgebung -> acht CPU´s (Kerne) mit 2,3 Ghz Takt, 32 GB RAM, sieben TB Speicherplatz (netto) auf eine Maschine mit einem Dual - Core Xeon mit 1,6 Ghz und vier GB RAM, insgesamt 1 TB Speicherplatz (netto) verlagert, um die restlichen Job´s auszuführen, was soll ich sagen: fühlt sich deutlich schneller an. Da ich nicht mit der Stoppuhr daneben stehe, “gefühlt”.

Fühlt sich aber deutlich performanter an. Anscheinend können die “Mehrprozessor - Quad - Systeme” unter dem MS - System nicht das, was sie könnten…

yo, würd ich bei den Fakten auch mal so sehen, aber
1.) scheint mir das auch für einen MS- Windows nicht recht normal (aber ich kenn mich mit Windows MP nicht aus)
2.) Betriebssystem-Diskussionen scheinen off limits zu sein :slight_smile:

spricht was gegen nen explain analyse delete … von 10 Datensätzen, output pasten und Tabellendef pasten?

Danke.

Schlage ich in der Hilfe nach. Weil: die Kombination sagt mir so nichts.

Es sei denn, Du hättest Zeit, mir zu Erklären, was für ein Effekt damit erzielt wird. Klingt interessant…

Und natürlich habe ich einen knallhart gesetzten Termin im Nacken :slight_smile: - da habe ich mal herzhaft Lachen dürfen. Entwicklung, Test, Betrieb und Ergebnis in 14 Tagen - Huahaha: allein der “scharfe Lauf” hat / wird soviel Zeit in Abspruch nehmen.

Habe ich versucht zu unterbinden. Versucht. Ich bin “Newbee”, was die pg angeht - meine SQL - Kenntnisse beruhen auf ORACLE und MS-SQL - Server - Datenbanken. Bei den hervorragend umgesetzten Implementierungen des ANSI - SQL - Standards - ich kann gar nicht soviel Essen, wie ich K***** könnte.

Tut auch nicht. Wer Dir da “Haue” anbietet, darf sich gerne mal bei mir Anschauen, wie “lahmarschig” so ein System werden kann.

Grüße
W.K.

ok, kein thema ist recht easy:

explain analyse [query] tut in einfachen Worten genau das, was da steht, es analysiert und naja ‘erklärt’ die abläufe, die innerhalb der datenbank zur Ausführung von [query] durchgeführt werden müssen


1.) connecte dich am Besten mittels Datenbankconsole (psql.exe sollte das teil unter WIndows heissen) auf die entsprechende Datenbank:
Linux syntax:
su postgres
psql datenbankname

kann sein, dass du unter Windows nen user (-U username) angeben musst, oder irgendwie anders in den useraccount postgres zu wechseln hast

2.) definier für deine ursprüngliche DELETE-QUERY eine ne zusätzliche where clause die basierend auf deiner ursprünglichen DELETE-ABFRAGE ungefähr 5 Datensätze erwischt.

Beispiel: DELETE FROM tblfiles WHERE ((jobname = ‘JobName’) AND (pkey < 6));

Wie gesagt, die 2. Bedingung - ‘(pkey < 6)’ ist ein Beispiel -musst Du anhand deiner Daten ermitteln :wink:

3.) In die Console gibst du nun
‘explain analyse DELETE FROM tblfiles WHERE ((jobname = ‘JobName’) AND (pkey < 6));’

ein.

Und schon bekommst DU ne analyse deiner DELETE-QUERY


Und die pastest Du am besten hier

Nun ja, wenn nur eine Query läuft ist das auch wieder normal.

Kannst Du Hardwareprobleme ausschließen? Bei solchen Aktionen (löschen) ist viel Schreibarbeit notwenig. Einmal die Daten selbst und dann auch das TX-Log. Als mein Server hier mal defekte Batterien auf dem RAID-Controller hatte und dieser deswegen den Write Cache abschaltete, lief hier auch alles in Zeitlupe. Bei Deinem System mit dieser Hardware vermute ich einfach mal, daß da bessere RAID-Controller mit Batterien verbaut wurden. Was auch wichtig ist: Aufteilung der Platten.

Andreas

Wenn die Jobs´s durch sind, kann ich die Angaben - eventuell um “Internas” bereinigt einstellen.

Wie gesagt, ich habe ein klein wenig Termindruck…

Grüße
W.K.

Die Aussage bezog sich auf die Indizierung / das Kopieren. Da laufen unter der JAVA - Anwendung 20 Threads. Aber in die pg darf immer nur einer schreiben. Auf dem “Achtzylinder” war das anscheinend zu wenig Last um vernünftig zu skalieren. Auf dem Dual - Core sieht das ganz anders aus und arbeitet (jetzt nicht mehr gefühlt, sondern gemessen) ca. 3,5 mal so schnell. Dafür rennen die beiden Kerne auch mit bis zu 99 % (Spitzen).

Ich nehme keine Hardwareprobleme an. Auch beim Rest finden ja reichlich Schreibzugriffe statt, die auch ins Log gehen. Und das läuft wie erwartet. Ich benutze jetzt einen Server, der über Gigabit - Verbindungen in die Server - Farm eingebunden ist und über einen anderen Server mit FC - Hostadapter auf ein SAN zugreift. SAN = Quelle, der Server mit der pg mit seinem Datenbereich = Ziel. Läuft vollauf brauchbar.

Für das Löschen habe ich einen anderen Ansatz - jetzt wieder auf dem “Achtender” versucht, ich greife mir über die JAVA - Anwendung immer 10 DS und bereite die für die “große Löschung” vor (Aufheben aller Abhängigkeiten / Abkoppeln von der Referenz). Alle 10 Blöcke wird das ins Log geschrieben. Lief noch, als ich für heute genug hatte. Das nimmt sich jetzt für 100 DS / Einträge etwas weniger als eine Minute. Das kommt mir schon sehr viel realistischer vor als die Laufzeit im pg-Admin.

Grüße
W.K.

Wenn Du in der DB was löschen willst, dann passiert das weder in einer Java-Anwendung noch in PG-Admin. Es passiert in der DB. Und wenn Du viel löschen willst und das in einer externen Anwendung in Blöcke aufteilst, dann mag das zwar nett aussehen, ist aber aus Sicher der DB nix weiter als viele kleine Transaktionen. Jede davon bringt eigenen Ballast mit.

Aber eines erreichst Du natürlich damit, falls das Java auf derselben Kiste rödelt: du beschäftigst die Kiste besser.

Andreas

Ich glaube, wir reden aneinander vorbei. Die zur späteren Löschung vorgesehenen Datensätze werden durch diesen Prozess “vorgemerkt” und von allen Abhängigkeiten befreit. Als Ergebnis erwarte ich eine neue Tabelle, die problemlos “gedropt” werden kann.

Ich habe erstmals mit einer Postgre zu tun - aber deshalb doch noch nie etwas mit einem Computer…

Du solltest beachten, daß bei jedem UPDATE eines Datensatzes ein toter Tupel entsteht. Und auch beim Löschen. Markierst Du also erst einmal alle zu löschenden Tupel (z.B. ein Flag in einem BOOL-Feld) und löscht dann alle diese Tupel, dann hast Du bei tausend gelöschter Tupel 2000 tote in der Tabelle.
Davon angesehen ist das auch doppelter Schreibaufwand für das TX-Log.

Sinnvoll ist was anderes.

Als Ergebnis erwarte ich eine neue Tabelle, die problemlos “gedropt” werden kann.

Du erzeugst eine Tabelle, nur damit diese gedropt werden kann?

Andreas