[OSM-Devserver] Partitionierung
Kai Krueger
kakrueger at gmail.com
Mo Apr 12 13:10:50 CEST 2010
On 04/12/2010 11:10 AM, Frederik Ramm wrote:
> Hallo,
>
> Peter Körner wrote:
>> Wobei wir auf Ptolemy festgestellt haben, dass der pending-index, der
>> auch so ein partially index ist, wesentlich weniger performant war als
>> ein richtiger index (bzw. oft einfach nicht benutzt wurde).
Wenn ich mich richtig erinnere war das Hauptproblem auf Ptolemy leicht
anders und zwar das ein "falsches" Analyze verursacht hat das die
Statistiken voellig daneben lagen und postgres somit den index nicht
verwenden wollte da er sich anscheinend nicht lohnte.
>
> Der partial index bringt dann was, wenn Du eine Abfrage machst, die
> genau die gleiche Where-Bedingung hat. Also fuer eine Abfrage wie
Selbst dann bringt er nur moeglicherweise etwas substantielles, denn
wenn die meiste zeit de queries mit etwas anderem verbracht wird hilft
es wenig.
Beispielhaft zwei queries aus dem normalen Mapnik schema.
Bei SELECT AsBinary("way",'NDR') AS geom,"disused","waterway" from
(select way,waterway,disused,name,
case when tunnel in ('yes','true','1') then 'yes'::text else
tunnel end as tunnel
from planet_osm_line
where waterway in
('weir','river','canal','derelict_canal','stream','drain','ditch')
and (bridge is null or bridge not in ('yes','true','1','aqueduct'))
order by z_order
) as water_lines WHERE "way" && SetSRID('BOX3D(-83163.48677427319
6648186.972131488,4891.969810252689 6736242.428716014)'::box3d,900913);
z.B. bringt ein partieller index auf "waterway is not null" einiges,
denn die query zeit (Laptop, mit nur England geladen und normalem
osm2pgsql schema) reduziert sich von ca. 150ms auf ca. 30ms
Bei dem Querry
SELECT AsBinary("way",'NDR') AS geom,"highway","tunnel" from
(select way,highway,service,
case when tunnel in ('yes','true','1') then 'yes'::text else
tunnel end as tunnel
from planet_osm_line
where highway in
('motorway','motorway_link','trunk','trunk_link','primary','primary_link','secondary','secondary_link','tertiary','tertiary_link','residential','unclassified','minor','road','service','pedestrian','raceway','living_street')
order by z_order) as roads
WHERE "way" && SetSRID('BOX3D(-83163.48677427319
6648186.972131488,4891.969810252689 6736242.428716014)'::box3d,900913);
hingegen bringt ein partieller index bereits kaum noch etwas.
Ohne index benoetigt der querry ca 960ms,
Fuer "where highway is not null" is es dann ca. 930ms
und bei dem vollen "where highway in
('motorway','motorway_link','trunk','trunk_link','primary','primary_link','secondary','secondary_link','tertiary','tertiary_link','residential','unclassified','minor','road','service','pedestrian','raceway','living_street')"
sind es immer noch 850ms.
Und das waren schon die recht einfachen queries. Viele der queries die
mapnik macht haben wesentlich mehr "or" Verknuepfungen, so dass man im
Prinzip fuer jeden querry (und davon gibt es viele) einen separaten
index benoetigt.
Nicht nur verliert man dann also bei den Updates, da man wesentlich mehr
indexe pflegen muss, sondern moeglicherweise auch bei den Abfragen, da
die cache efficiency moeglicherweise deutlich reduziert wird da die
daten dank der zusaetzlichen indexe groesser geworden sind.
Bevor man irgendwelche indexe hinzufuegt sollte man also recht genau
eine statistische Analyse machen, welche Abfragen im Durchschnitt ab
meisten Zeit benoetigen ( also die Kombination aus wie haeufig werden
die Abfragen verwendet und wie lange braucht jede davon) und ob das
insgesamt prozentual ein nennenswerter Anteil des Gesamten ist.
Eine moegliche alternative ist die Datenbank anhand des way indexes zu
clustern, da das moeglicherweise die Zahl der Diskzugriffe reduziert.
Das wurde ca. letzte Woche wohl auf dem osm.org tile server versucht,
ich weis allerdings nicht wieviel es gebracht hat.
>
> select * from roads where way && (bbox...) and highway=primary
>
> sollte es eigentlich nichts besseres geben als einen Index, der mit
>
> create index bla on blub using GIST(way) where highway=primary
>
> erzeugt wurde. (Auf jeden Fall sollte so ein Index bei so einer Abfrage
> immer besser sein, als wenn man einen GIST(way) und separat einen Index
> nach Highway-Typ haette.)
>
> Inwiefern PostGIS den partial index auch fuer der partial-Bedingung
> *aehnliche* Abfragen benutzt, muesste man im konkreten Fall mit explain
> rausfinden.
So wie es aussieht verwendet postgres die partiellen indexe wenn sie
einen superset der abgefragten daten beinhaltet. Es muss aber vermutlich
ein kompletter superset sein, sodass Teile einer or Bedingungen nicht
funktionieren duerften.
Kai
>
> Bye
> Frederik
> _______________________________________________
> Devserver mailing list
> Devserver at lists.openstreetmap.de
> http://lists.openstreetmap.de/mailman/listinfo/devserver