writable view performance #1
Hallo Leute,
ich bin gerade dabei, eine Anwendung (ein Auktions-Crawler,
siehe http://auctionwatch.metux.de/) ein wenig zu optimieren.
Zum besseren Verständnis hol ich erstmal etwas weitera aus:
* Aus Nutzer-Sicht erlaubt die Anwendung erstmal, bestimmte
Feeds von ebay (spaeter auch andere) zu abonieren. Es landen
dann immer die jeweils neuen Artikel in der incoming-queue.
Als gelesen markierte Artikel werden dem Nutzer nicht mehr
angezeigt, bleiben aber in der DB (uA. um nicht nach dem
nächsten scan wieder zu erscheinen).
* Für jeden Nutzer können Filter-Regeln gesetzt werden
(änhlich procmail ;-)), nach denen Artikel von einer
Queue irgentwo anders hin umsortiert werden können.
(zB. kann man so anhand Thumbnail-md5 und/oder Preis
wiederkehrende zu teure oder uninteressante Artikel gleich
wegsortieren :))
* Die Artikel werden zunächst in der Tabelle base.articles
gespeichert. Dort wird das Auktionshaus via ID zur Tabelle
base.platform referenziert.
* Die Suchtergebnisse der einzelnen Nutzer (incl. seen-flag,
queue, ...) stehen in base.user_results - dort werden sowohl
Nutzer als auch Artikel via ID nach base.users bzw. base.articles
referenziert.
* Der Crawler greift über (zT. schreibbare) Views crawler.* zu.
Er wirft die neuen Suchergebnisse nach crawler.user_results,
wo username und platform mit dem Namen dargestellt werden.
* Der Filter-Prozess arbeitet sukzessive die Nutzer bzw deren
Regeln durch und löst Queries der Form aus:
UPDATE crawler.user_results
SET queue=3D'{ ... Ziel-Queue ...}'
WHERE
NOT seen AND
queue =3D '{ ... Quell-Queue ...}' AND
username =3D '{ ... Nutzer ... }' AND
{ ... Filter ... }
;
Lt. EXPLAIN ANALYZE werden da einige (IMHO) wunderliche Dinge getan, zB.
* die Table base.platform wird eingebaut (join), auch wenn die daraus
entstammenden Felder nicht benutzt werden. Kann das denn nicht
wegoptimiert werden ?
* bei base.platform und base.user werden keine Indices benutzt.
Okay, die sind noch sehr klein -> lohnt vielleicht nocht nicht ?
* ich hab auf das seen-Flag (auch in Verbindung mit allerlei anderen
hier benutzten Feldern) Indices gesetzt - keiner wird verwendet.
Eigentlich hatte ich gehofft, daß wenigstens ein Index schonmal
zum rausfischen der eigentlich interessanten (NOT seen) Rows
benutzt werden könnte, und nicht über die stetig wachsende
Masse der seen-markierten gescannt werden muß.
Hat jemand vielleicht noch ein paar Tips, wo ich noch etwas
optimieren könnte ?
thx
--
------------------------------------------------------------ ---------
Enrico Weigelt =3D=3D metux IT service - http://www.metux.de/
------------------------------------------------------------ ---------
Please visit the OpenSource QM Taskforce:
http://wiki.metux.de/public/OpenSource_QM_Taskforce
Patches / Fixes for a lot dozens of packages in dozens of versions:
http://patches.metux.de/
------------------------------------------------------------ ---------
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo [at] postgresql.org so that your
message can get through to the mailing list cleanly
Re: writable view performance #1
Enrico Weigelt <weigelt [at] metux.de> schrieb:
> * Die Suchtergebnisse der einzelnen Nutzer (incl. seen-flag,
^^^^^
Hehe ;-)
> queue, ...) stehen in base.user_results - dort werden sowohl
> Nutzer als auch Artikel via ID nach base.users bzw. base.articles
> referenziert.
> * Der Crawler greift über (zT. schreibbare) Views crawler.* zu.
> Er wirft die neuen Suchergebnisse nach crawler.user_results,
> wo username und platform mit dem Namen dargestellt werden.
> * Der Filter-Prozess arbeitet sukzessive die Nutzer bzw deren
> Regeln durch und löst Queries der Form aus:
>
> UPDATE crawler.user_results
> SET queue=3D'{ ... Ziel-Queue ...}'
> WHERE
> NOT seen AND
> queue =3D '{ ... Quell-Queue ...}' AND
> username =3D '{ ... Nutzer ... }' AND
> { ... Filter ... }
> ;
>
> Lt. EXPLAIN ANALYZE werden da einige (IMHO) wunderliche Dinge getan, zB=
..
>
> * die Table base.platform wird eingebaut (join), auch wenn die daraus
> entstammenden Felder nicht benutzt werden. Kann das denn nicht
> wegoptimiert werden ?
Wenn diese Table mit eingebaut wird, dann wird das wohl nötig sein.
Offensichtlich wird diese irgendwo in Deinen Views mit referenziert.
> * bei base.platform und base.user werden keine Indices benutzt.
> Okay, die sind noch sehr klein -> lohnt vielleicht nocht nicht ?
Möglich. Bei kleinen Tabellen ist die Verwendung eines Indexes u.U.
'teurer' als der direkte table-scan, weil er mehr Plattenzugriffe
braucht (erst Index, dann table) und die Table möglicherweise so klein
ist, daß da ein einzelner Block auf der Spindel ist -> ein einzelner
Zugriff.
> * ich hab auf das seen-Flag (auch in Verbindung mit allerlei anderen
> hier benutzten Feldern) Indices gesetzt - keiner wird verwendet.
BOOL-Felder und Indexe, naja, solche Felder haben keine hohe
Selektivität. Näheres würde ein explain analyse verraten.
> Eigentlich hatte ich gehofft, daß wenigstens ein Index schonmal
> zum rausfischen der eigentlich interessanten (NOT seen) Rows
> benutzt werden könnte, und nicht über die stetig wachsende
> Masse der seen-markierten gescannt werden muß.
>
>
> Hat jemand vielleicht noch ein paar Tips, wo ich noch etwas
> optimieren könnte ?
- schaue Dir relevante Abfragen mit EXPLAIN ANALYSE an
- Tabellen, die vielen =C4nderungen (Updates/Deletes) unterliegen
benötigen öfters mal ein Vacuum
- welche Version von PG?
- Frohe Weihnachten!
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate
Re: writable view performance #1
* Andreas Kretschmer <akretschmer [at] spamfence.net> schrieb:
> Enrico Weigelt <weigelt [at] metux.de> schrieb:
> > * Die Suchtergebnisse der einzelnen Nutzer (incl. seen-flag,
> ^^^^^
> Hehe ;-)
*lol*
> > * die Table base.platform wird eingebaut (join), auch wenn die daraus=
> > entstammenden Felder nicht benutzt werden. Kann das denn nicht
> > wegoptimiert werden ?
>
> Wenn diese Table mit eingebaut wird, dann wird das wohl nötig sein.
> Offensichtlich wird diese irgendwo in Deinen Views mit referenziert.
Im View an sich ja, aber nicht in der konkreten Query.
> > * bei base.platform und base.user werden keine Indices benutzt.
> > Okay, die sind noch sehr klein -> lohnt vielleicht nocht nicht ?
>
> Möglich. Bei kleinen Tabellen ist die Verwendung eines Indexes u.U.
> 'teurer' als der direkte table-scan, weil er mehr Plattenzugriffe
> braucht (erst Index, dann table) und die Table möglicherweise so klein
> ist, daß da ein einzelner Block auf der Spindel ist -> ein einzelner
> Zugriff.
Ja, das dacht ich mir schon. Mal sehen, wie sich das entwickelt,
wenn es ein paar mehr User sind. (darfst Dich gern registrieren ;-))
> > * ich hab auf das seen-Flag (auch in Verbindung mit allerlei anderen
> > hier benutzten Feldern) Indices gesetzt - keiner wird verwendet.
>
> BOOL-Felder und Indexe, naja, solche Felder haben keine hohe
> Selektivität. Näheres würde ein explain analyse verraten.
Das bringt wohl nicht viele Punkte ?
Ich hab unterdessen die Table user_results aufgespaltet - was
früher seen=3Dtrue hatte, landet jetzt in einer eigenen Table
und wird nur in jene Views eingebaut, die wirklich auch die
ungelesen zeigen sollen.
Schneller ist's dadurch aber auch nicht geworden :(
Die periodischen Sortier-Queries brauchen immernoch ca. 0.7sec
bis 1.2sec je Stk.
> > Hat jemand vielleicht noch ein paar Tips, wo ich noch etwas
> > optimieren könnte ?
>
> - schaue Dir relevante Abfragen mit EXPLAIN ANALYSE an
klar :)
> - Tabellen, die vielen =C4nderungen (Updates/Deletes) unterliegen
> benötigen öfters mal ein Vacuum
Wie oft ? Gibts da eine Richtschnur ?
BTW: werden eigentlich überflüssige updates (also bei denen
praktisch dieselben Werte wieder geschrieben werden) von postgres
selbst abgefangen oder gibts da jedesmal echte Schreiboperationen ?
> - welche Version von PG?
8.0.8
> - Frohe Weihnachten!
ACK.
cu
--
------------------------------------------------------------ ---------
Enrico Weigelt =3D=3D metux IT service - http://www.metux.de/
------------------------------------------------------------ ---------
Please visit the OpenSource QM Taskforce:
http://wiki.metux.de/public/OpenSource_QM_Taskforce
Patches / Fixes for a lot dozens of packages in dozens of versions:
http://patches.metux.de/
------------------------------------------------------------ ---------
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend
Re: writable view performance #1
Enrico Weigelt <weigelt [at] metux.de> schrieb:
> > > * die Table base.platform wird eingebaut (join), auch wenn die dara=
us
> > > entstammenden Felder nicht benutzt werden. Kann das denn nicht
> > > wegoptimiert werden ?
> >
> > Wenn diese Table mit eingebaut wird, dann wird das wohl nötig sein.
> > Offensichtlich wird diese irgendwo in Deinen Views mit referenziert.
>
> Im View an sich ja, aber nicht in der konkreten Query.
Ist in der konkreten Query der View mit drin?
> > > * ich hab auf das seen-Flag (auch in Verbindung mit allerlei andere=
n
> > > hier benutzten Feldern) Indices gesetzt - keiner wird verwendet.
> >
> > BOOL-Felder und Indexe, naja, solche Felder haben keine hohe
> > Selektivität. Näheres würde ein explain analyse verraten.
>
> Das bringt wohl nicht viele Punkte ?
Depends. Wenn die überwiegende Mehrheit der Datensätze die
WHERE-Bedingung erfüllt, dann wohl nicht.
> > - Tabellen, die vielen =C4nderungen (Updates/Deletes) unterliegen
> > benötigen öfters mal ein Vacuum
>
> Wie oft ? Gibts da eine Richtschnur ?
Ein simples VACUUM unmittelbar nach gröberen =C4nderungen schadet selte=
n.
>
> BTW: werden eigentlich überflüssige updates (also bei denen
> praktisch dieselben Werte wieder geschrieben werden) von postgres
> selbst abgefangen oder gibts da jedesmal echte Schreiboperationen ?
Kann ich grad nicht sagen, müßte man mal ausprobieren. Vermutlich abe=
r
ja. Aber Versuch macht klug:
test=3D# \d words
Table "public.words"
Column | Type | Modifiers
--------+------+-----------
w | text |
Indexes:
"idx_words" btree (lower(w) varchar_pattern_ops)
test=3D#
test=3D# select count(*) from words;
count
-------
56840
(1 row)
test=3D# select pg_relation_size('words');
pg_relation_size
------------------
2621440
(1 row)
test=3D# update words set w=3Dw;
UPDATE 56840
test=3D# select pg_relation_size('words');
pg_relation_size
------------------
5234688
(1 row)
Andreas
--
Really, I'm not out to destroy Microsoft. That will just be a completely
unintentional side effect. (Linus Torvalds)
"If I was god, I would recompile penguin with --enable-fly." (unknow)
Kaufbach, Saxony, Germany, Europe. N 51.05082=B0, E 13.56889=
=B0
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faq