Das habe ich mal ausprobiert am Beispiel des GfK GeoMarketing Deutschlanddatensets. Dazu habe ich mir folgendes Result Set überlegt:
Ich brauche eine Auflistung der
- administrativen Ebene 3 (Name und Gemeindekennziffer der Stadt- und Landkreise)
- administrativen Ebene 4 (Name und Gemeidekennziffer Gemeinden)
- und der den Gemeinden zugeordneten 5-stelligen Postleitzahlen.
select d.id , d.name "Name Stadt-/Landkreis", d.new___z "Anzahl EW Stadt-/Landkreis", g.id "ID Gemeinde", g.name "Name Gemeinde", g.new___z "Anzahl EW Gemeinde", p.id "PLZ" from de_municipalities_2010 g, de_districts_2010 d, de_5digpc_2010 p where substr(g.id,1,5) = d.id and sdo_relate(g.geometry, p.geometry, 'mask=anyinteract') = 'TRUE' and p.id = '16515' group by d.id , d.name, d.new___z, g.id, g.name, g.new___z, p.id order by d.id , d.name, g.id, g.name, p.id /
Ein bisschen mutiger geworden, wird der Filter dann gelockert, um ihn ganz zu entfernen. Denn Ziel war ja, den kompletten Datenbestand beider Tabellen räumlich in Beziehung zu setzen, um auch die Postleitzahlen zu ermitteln, welchen den Gemeinden zugeordnet sind. Das sind knapp 11600 Gemeinden und gut 8200 PLZs.
So und das war es dann auch erst mal für den Nachmittag, den Abend ... und auch am nächsten Morgen hatte sich noch kein Result Set einstellen wollen.
Also muss es wohl noch besser gehen.
Folgende überlegungen führten dann zu weiteren Vesuchen:
- Ich stelle sicher, dass für beide Tabellen der räumliche Index benutzt wird.
- Ich nutze erst mal nur den Primary Filter, um ein annäherndes Ergebnis zu erhalten. Danach wird der exakte Vergleich nur noch mit dem dann schon eingeschränkten Datenset vorgenommen.
Wie funktioniert dabei SDO_JOIN?
select rowid1 as municipalities_id, rowid2 as plz5_id from table( sdo_join( 'DE_MUNICIPALITIES_2010', 'GEOMETRY', 'DE_5DIGPC_2010', 'GEOMETRY', 'mask=anyinteract')) /
Allerdings fehlt ja auch noch der Join mit der 3. Tabelle und auch group by und order by sollen schon sein und kosten die Datenbank so einiges an Ressourcen und damit Zeit.
Also muss der Rest auch noch her und ergibt dann diese SQL Abfrage:
with spatial_join_result as ( select rowid1 as municipalities_id, rowid2 as plz5_id from table( sdo_join( 'DE_MUNICIPALITIES_2010', 'GEOMETRY', 'DE_5DIGPC_2010', 'GEOMETRY', 'mask=anyinteract'))) select d.name "Name Stadt-/Landkreis", d.new___z "Anzahl EW Stadt-/Landkreis", g.name "Name Gemeinde", g.new___z "Anzahl EW Gemeinde", p.id "PLZ" from spatial_join_result a, de_municipalities_2010 g, de_5digpc_2010 p, de_districts_2010 d where a.municipalities_id = g.rowid and a.plz5_id = p.rowid and sdo_relate(g.geometry, p.geometry, 'mask=anyinteract') = 'TRUE' and substr(g.id, 1, 5) = d.id -- Hierarchische Verknüpfung Admin Ebene 3 mit Admin Ebene 4 group by d.name, d.new___z, g.name, g.new___z, p.id order by d.name, d.new___z, g.name, g.new___z, p.id /
Für diejenigen Leserinnen und Leser dieses Blogeintrags, die im Besitz einer (gern auch mehrerer) Oracle DB Enterprise Edition Lizenz sind, sei gesagt, dass sie damit noch mehr Optimierungspotential haben. Das verheissungsvolle Wort an dieser Stelle ist Parallisierung.
Wie das funktioniert, dafür verweise ich jetzt einfach mal auf diesen Link. Denn sonst verpasse ich vielleicht noch meinen Flieger in den Urlaub.