ich habe zwei Tabellen in der gleichen Datenbank,
in der einen Tabelle sind ca. 6.5 Mio Einträge, in der anderen ca 4 Mio.
Die Spalten und Indizes sind gleich. Die eine Tabelle enthält lediglich noch doppelte Einträge.
Abfragen auf der größeren Tabelle gehen wesentlich schneller als Abfragen auf der kleineren. Was kann das sein ?
hier noch ein queryplan von select count(*), was mich verwundert ist dass,bei der langsamen tabelle das erste rows=9849297 ist
Die Fehl-Schätzung deuted auf schlecht gepflegte Statistiken hin. Mache mal ein analyse auf diese Tabelle. Die Tabelle scheint auch jede Menge toter Tupel zu enthalten → vacuum anwenden.
Generell sind count(*) - Abfragen ohne WHERE langsam, da sie einen Seq-Scan nach sich ziehen. Im übrigen hat die eine Tabelle nicht ca. 4, sondern über 5 Millionen Einträge.
INFO: vacuume »public.ways_final«
INFO: Index »ways_final_pkey1« enthält 5092181 Zeilenversionen in 43223 Seiten
DETAIL: 0 Indexzeilenversionen wurde entfernt.
355 Indexseiten wurden gelöscht, 355 sind gegenwärtig wiederverwendbar.
CPU 0.21s/0.06u sec elapsed 7.50 sec.
INFO: Index »source_idxf« enthält 5092181 Zeilenversionen in 38427 Seiten
DETAIL: 0 Indexzeilenversionen wurde entfernt.
17 Indexseiten wurden gelöscht, 17 sind gegenwärtig wiederverwendbar.
CPU 0.19s/0.05u sec elapsed 4.72 sec.
INFO: Index »target_idxf« enthält 5092181 Zeilenversionen in 38581 Seiten
DETAIL: 0 Indexzeilenversionen wurde entfernt.
14 Indexseiten wurden gelöscht, 14 sind gegenwärtig wiederverwendbar.
CPU 0.21s/0.08u sec elapsed 4.39 sec.
INFO: Index »geom_idxf« enthält 5092181 Zeilenversionen in 100178 Seiten
DETAIL: 0 Indexzeilenversionen wurde entfernt.
0 Indexseiten wurden gelöscht, 0 sind gegenwärtig wiederverwendbar.
CPU 0.50s/0.18u sec elapsed 10.89 sec.INFO: »ways_final«: 0 entfernbare, 5092181 nicht entfernbare Zeilenversionen in 1035677 Seiten gefunden
DETAIL: 0 tote Zeilenversionen können noch nicht entfernt werden.
Es gibt 10980544 unbenutzte Itemzeiger.
859463 Seiten enthalten nützlichen freien Platz.
0 Seiten sind vollkommen leer.
CPU 7.29s/2.68u sec elapsed 151.51 sec.
WARNUNG: Relation »public.ways_final« enthält mehr als »max_fsm_pages« Seiten mit nutzbarem freiem Platz
HINT: Consider using VACUUM FULL on this relation or increasing the configuration parameter "max_fsm_pages".INFO: vacuume »pg_toast.pg_toast_34678«
INFO: Index »pg_toast_34678_index« enthält 1156 Zeilenversionen in 11 Seiten
DETAIL: 0 Indexzeilenversionen wurde entfernt.
0 Indexseiten wurden gelöscht, 0 sind gegenwärtig wiederverwendbar.
CPU 0.00s/0.00u sec elapsed 0.01 sec.INFO: »pg_toast_34678«: 0 entfernbare, 1156 nicht entfernbare Zeilenversionen in 372 Seiten gefunden
DETAIL: 0 tote Zeilenversionen können noch nicht entfernt werden.
Es gibt 2072 unbenutzte Itemzeiger.
362 Seiten enthalten nützlichen freien Platz.
0 Seiten sind vollkommen leer.
CPU 0.00s/0.00u sec elapsed 0.11 sec.
Abfrage war erfolgreich nach 151766 ms. Keine Zeilen geliefert.
INFO: analysiere »public.ways_final«
INFO: »ways_final«: 3000 von 1035677 Seiten gelesen, enthalten 14711 lebende Zeilen und 0 tote Zeilen; 3000 Zeilen in Stichprobe, schätzungsweise 5078615 Zeilen insgesamt
Abfrage war erfolgreich nach 10609 ms. Keine Zeilen geliefert.
Hier die letzten Zeilen von
VACUUM ANALYZE VERBOSE;
INFO: Free-Space-Map enthält 123138 Seiten in 21 Relationen
DETAIL: Es sind insgesamt 153600 Page-Slots in Benutzung (einschließlich Overhead).
890592 Page-Slots werden benötigt, um den gesamten freien Platz verwalten zu können.
Aktuelle Begrenzungen sind: 153600 Page-Slots, 1000 Relationen, ergibt 965 kB Speicherverbrauch.
HINWEIS: Anzahl der benötigten Page-Slots (890592) überschreitet max_fsm_pages (153600)
HINT: Erhöhen Sie eventuell den Konfigurationsparameter »max_fsm_pages« auf über 890592.
Abfrage war erfolgreich nach 756438 ms. Keine Zeilen geliefert.
was anderes als rumdoktorn geht doch sowieso nicht …
die allermeisten parameter muss man schaetzen - berechnungsvorschriften gibt es nur sehr wenige
mir faellt hier nur auf, dass am anfang von select count(*) gesprochen wurde … ein problem habt ihr entdeckt … und jetzt sind wir wieder bei unscharfen aussagen wie “langsam” oder “schnell” und niemand fragt mehr was denn nun “langsam” oder “schnell” ist
Wie du so schön sagst: es gibt keine Berechnungsvorschriften.
Einfach weil zu viele Parameter eine Rolle spielen - sowohl in der Konfiguration der Datenbank wie auch des Betriebssystems, der Hardware, der Datenbasis, der Anzahl und Art der Zugriffe und und und …
Wenn der “SELECT COUNT(*)” der einzige Anwendungsfall ist (was ich nicht glaube), kann man den wegoptimieren. Ob man damit den Rest der Probleme erschlägt, sei dahingestellt. Bislang kennen wir ein konkretes Problem und 4 Zeilen aus der Konfiguration, mehr nicht. Was soll man dazu noch groß sagen?
ich wollte nur deinen vorwurf entkräften … weil “optimierung” immer irgendwas von rumdoktoren hat
Wenn der “SELECT COUNT(*)” der einzige Anwendungsfall ist (was ich nicht glaube),
ich glaube das auch nicht - daher die implizite geheime frage … an den OP … WAS GENAU ist denn “langsam” … weil tabellen sind niemals langsam - nur Opertionen z.B. Abfragen … also WELCHE
mein konkretes problem war dass auf diesen tabellen ein routingalgorithmus (pgrouting) läuft, der war viel langsamer als auf meiner tabelle, die ich vorher hatte, die aber doppelte wege enthält…dann habe ich gemerkt dass die tabelle bei allen anfragen langsamer ist und nur noch mit count(*) getestet.
nach dem restart und erneutem vacuum keine änderung.
count() ist eine realitätsferne Abfrage - meist zumindest. Es macht auch exakt keinerlei Sinn, sich einen Plan von select count() from table; anzuschauen, wenn andere Abfragen als diese zu beschleunigen sind.
ich wollte auch nicht den count(*) optimieren. nur wenn der auf ner tabelle mit weniger von den gleichen einträgen 3 mal so lang braucht stimmt doch allgmein mit der tabelle irgendwas nicht
vorrausgesetzt, dass die beiden tables WIRKLICH strukturell gleich sind, auf dem gleichen system in der gleichen db (also mit der gleichen config) laufen und auch vergleichbare daten enthalten, kann nur daran liegen (<-- randbedingung), dass du
immernoch kein VACUUM FULL ausgefuehrt hast oder
die datenbank stark fragmentiert ist - auf dateisystemebene …
schaetzungsweise ist die “kleine table” sehr lang in benutzung … und wurde auch oft geschrieben … -> gescheites vacuum noetig
die andere grosse ist wahrscheinlich frisch erzeugt wurden
wenn du auf unterschiedlichen systemen/betriebsystemen rumprobierst (was wir nicht hoffen) hat das alles keinen wert
ja, die sind auf dem selben system in der selben db.
Es ist so dass die große Tabelle älter ist als die andere.
die neue Tabelle ist mit einem select into entstanden (von noch einer anderen tabelle), danach hab ich den primary key und indizes gesetzt.
dann hab ich dublicates entfernt mit
DELETE FROM ways_final WHERE gid IN (SELECT b.gid FROM ways_final a,
ways_final b
WHERE a.the_geom ~= b.the_geom AND a.gid > b.gid);
lasse jetzt gerade das vacuum full laufen, hatte eben nur vacuum auf die tabelle gemacht
wie ads und akretschmer dir bereits in ungewöhnlich diplomatischer weise nahe zu legen versuchten, solltest du das bereits vor geraumer zeit getan haben … weil du hast den wink mit dem zaunspfahl selbst gepostet → output von irgendeinem vacuum verbose
danach wäre interessant dass du die (zwar wenig relevanten) tests nochmal probierst … so ein kompletter table-scan sagt ja auch was über den zustand der tabelle aus