[OSM-Devserver] Schnelleres Rendern durch Preprozessing

Nop ekkehart at gmx.de
Sa Nov 27 18:35:37 CET 2010


Hallo!

Am 18.05.2010 08:46, schrieb Jochen Topf:
> On Mon, May 17, 2010 at 10:54:42PM +0200, Nop wrote:
>> Normalerweise haben die Mapnik Layers eine ziemlich komplizierte
>> SELECT-Anweisung, in der ein Haufen Abfragen auf die einzelnen Tags mit
>> OR verknüpft werden. Die sind generell ziemlich unhandlich und wurden
>> von der DB immer mit einem Table Scan abgehandlet, egal was ich an
>> Tricks mit Indexen versucht habe.
>>
>> Ich mache mit den Daten ja ein Preprocessing, bevor sie in die DB
>> kommen. Dabei gibt es einen Moment, wo ich bereits weiß, in welcher
>> Layer bestimmte Objekte später angezeigt werden sollen. Also habe ich
>> die Nummer dieser Layer mit in die DB geschrieben. Damit vereinfacht
>> sich das Statement auf SELECT ... WHERE layer =<nummer>. Auf layer
>> liegt natürlich ein Index. Ich habe den Eindruck, daß die DB jetzt den
>> Index nutzt und die Tiles so deutlich schneller gerendert werden.
>
> Wenn Du eh schon weisst, was auf welchem Layer ist und alles nur auf genau
> einem Layer vorkommt, dann wäre es noch besser, für jeden Layer eine eigene
> Tabelle anzulegen. Dann ists nämlich ganz klar, dass er den Geometrie-Index
> auf dieser Tabelle benutzen kann. Bei der von Dir beschriebenen Lösung muss
> sich die Datenbank entscheiden, ob sie den Geometrie-Index benutzt oder den
> Layer-Index.

Das mit einer eigenen Tabelle würde wieder ein anderes Datenbankschema 
voraussetzen, als es osm2pgsql benutzt. Ich habe nochmal ein wenig 
rumgespielt mit diesen Ideen, und bin dabei auf ein paar Erkenntnisse 
gestoßen, die dem einen oder anderen nützlich sein könnten.

1. Zusätzliche Indexe

Wenn es ein extremes Select-Kriterium gibt, lohnt es sich manchmal 
darauf einen Index anzulegen. Bei meinen damaligen Versuchen hat sich 
besonders ein Index auf "bridge" und einer auf "tunnel" bewährt, den die 
DB mit Begeisterung genommen hat.

2. Gemischter Index

Es ist möglich einen gemischten Index aus Geometrie und Tagging zu 
erzeugen. Dazu muß das Addon btree_gist installiert werden. Dann sind 
Indexe wie z.B. auf GIST ( way, layer ) möglich. Die DB bevorzugt die 
häufig gegenüber dem reinen Gemoetrieindex.

3. Partielle Indexe

Diese Technik hat bei mir einen echten Durchbruch beim Rendern gebracht 
und sollte generell bei allen Anwendungen funktionieren. Ich habe für 
jede Layer in den Mapnik-Rules einen Teilindex mit Geometriedaten 
erzeugt, der genau zu der where-Bedingung für diese Layer paßt. Die DB 
liebt sowas! Also z.B.

  gist ( way ) WHERE bridge is not null;

Bei mir war das besonders einfach, weil die Bedingung nur 
layer=<integer> lautet, aber es dürfte auch generell gehen. Besonders 
gut wieder für kleine Subsets wie Brücken und Tunnel.

bye
                Nop