2016-03-21 24 views
2

Tablo birleşimi oluşturmakta sorun yaşıyorum. Sorgu sonsuza kadar çalışır. Tüm özelliklere sahip bir tabloda açık sokak haritası bisiklet rotaları var. PostgreSQL - OSM verisine çok yavaş tablo birleştirme

Table planet_osm_line 
osm_id bigint, 
route text, 
name text, 
network text, 
osmc_color text, 
reversed text, 
state text, 
"instance:cycle" text, 
"relation:id" text, 
ref text, 
description text, 
distance text, 
tags hstore, 
way geometry(LineString,900913) 

hatların bazı

(bir şekilde 2 ya da daha fazla yollar) çoğaltılır bu yüzden başka bir tabloya özgü çizgiler, süzüldü ve planet_osm_line verileri ile birleştirmek için çalışılmıştır:

DROP TABLE IF EXISTS public.bicycle_merge; 
CREATE TABLE public.bicycle_merge AS 

WITH singleRow as ( 
    select count(way), way 
    from planet_osm_line 
    WHERE route IN ('bicycle') 
    group by way 
    having count(way) = 1 
) 
SELECT P.* 
FROM planet_osm_line P 
JOIN singleRow S 
    ON P.way = S.way 
; 

Bu sorgu Sonsuza dek koşuyor .... Acemi sorumu affet ama ne yapıyorum yanlış?

"Nested Loop (cost=28767.43..172920474.87 rows=5892712 width=335)" 
" Join Filter: (p.way = s.way)" 
" CTE singlerow" 
" -> GroupAggregate (cost=27040.24..28767.43 rows=76764 width=218)" 
"   Filter: (count(planet_osm_line1.way) = 1)" 
"   -> Sort (cost=27040.24..27232.15 rows=76764 width=218)" 
"    Sort Key: planet_osm_line1.way" 
"    -> Seq Scan on planet_osm_line1 (cost=0.00..4543.55  rows=76764 width=218)" 

Planet_osm_line tablosu yaklaşık 70.000 satıra sahiptir. Eşsiz geometriler yaklaşık 50.000'dir. Bu sorgu, küçük bir veri kümesi üzerinde çalışıyor ancak şu anda tüm ülkedeki (Polonya) bisiklet yolları ile uğraşıyorum. Şimdiden çok teşekkür ederim!

+0

'gruba göre sayma (yol) = 1 'aslında hiçbir şey yapmaz,' planet_osm_line''dan farklı bir yol seçebilirdiniz. Ama bu, bir optimizasyon bariyeri olarak hareket eden bir CTE'nin kullanılmasını gerektirmiyor, bu yüzden sadece 'SELECT DISTINCT ON (yol)' u kullanabiliyordunuz * FROM planet_osm_line WHERE rotası = 'bisiklet' SİPARİŞİ yolundan. – pozs

+0

Bu aslında çalışır ancak aynı zamanda çiftleri olan satırları da listeler. Bundan kaçınmak istiyorum. Tabloda sadece var olan çizgilere ihtiyacım var. – Voyteck

+0

bir yinelenen tanımlar? '' '' '(' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'ile birden çok satırı kaldırmalıdır Ya da çoğaltılmış olan tüm satırları (ve sadece bir tanesi hariç) kaldırmak ister misiniz? – pozs

cevap

6

İki düz geometriye katılıyorsunuz. Bu, olası tüm eşleşmeler arasında, bayt için baytlık baytların ikili karşılaştırmasını yaptığınız anlamına gelir. Bu gerçekten ciddi bir zaman alacaktır. EXPLAIN ANALYZE’da CTE’nin 28.767’lik bir maliyeti vardır; Birleştirme, bir faktör 6,000 büyüktür. Bunun yerine

, iki geometriler (OSM düzgün coğrafi olarak kodlanmıştır beri hiçbir satır kavşak bulunduğundan varsayabiliriz) birbirine temas eğer test etmelisiniz: satır Sette

WITH singleRow AS ( 
    SELECT count(way), way 
    FROM planet_osm_line 
    WHERE route IN ('bicycle') 
    GROUP BY way 
    HAVING count(way) = 1 
) 
SELECT P.* 
FROM planet_osm_line P 
JOIN singleRow S ON ST_Contains(P.way, S.way);

siz yapabilirsiniz böyle almak daha sonra, daha küçük çizgileri bir araya getirmek için ST_MakeLine() işlevini uygulayın.

+1

Harika cevap. ST_Touches'ı ST_Contains olarak değiştirdim ve gayet iyi çalışıyor. ST_Touches düzgün çalışmadı ama yine de teşekkür ederim :) – Voyteck

+0

ST-Touches() işe yaramazsa Garip güncellendi. – Patrick

+0

Sorgum 14 saniye sürdü. Bu çok kabul edilebilir. Tekrar teşekkürler! – Voyteck