[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