Kết hợp khóa / giá trị Hstore và truy vấn không gian quá chậm để xử lý các trích xuất OSM lớn hơn


13

Tôi đang cố gắng tính toán một số thống kê cho dữ liệu OSM bằng PostgreSQL 9.3.5 và PostGIS 2.1.4. Tôi bắt đầu với một trích xuất bavaria nhỏ mà tôi đã tải xuống từ Geofabrik. Lược đồ db là lược đồ API 0.6 thông thường, dữ liệu được nhập thông qua cách tiếp cận kết xuất vào Postgres (sử dụng các tập lệnh pssnapshot_schema_0.6 * .sql đi kèm với thẩm thấu). ANALYZE VACUUM cũng đã được thực hiện.

Điều duy nhất được thực hiện mà tôi đang sử dụng là một bảng đa giác chứa nhiều đa giác cho tất cả các quan hệ ranh giới hành chính. Hình học đa giác không được đơn giản hóa theo bất kỳ cách nào.

Những gì tôi đang cố gắng đạt được là đếm tất cả các nút bên trong quản trị = 6 ranh giới của bavaria. Đây là truy vấn SQL của tôi:

SELECT relpoly.id, count(node) 
FROM bavaria.relpolygons relpoly, bavaria.nodes node
WHERE relpoly.tags @> '"boundary"=>"administrative","admin_level"=>"6"'::hstore 
AND ST_Intersects(relpoly.geom, node.geom)
GROUP BY relpoly.id;

Thời gian chạy của truy vấn này rất tệ vì Postgres đang thực hiện nối vòng lặp lồng nhau và quét qua tất cả các nút cho mỗi ranh giới admin = 6. FYI, bavaria được chia thành 98 admin = 6 đa giác và có khoảng 30 triệu nút trong trích xuất bavaria.

Có thể tránh việc thực hiện truy vấn tối ưu phụ này và nói với Postgres rằng nó chỉ nên quét tất cả các nút một lần (ví dụ: bằng cách tăng bộ đếm cho đa giác tương ứng trong tập kết quả hoặc bằng cách sử dụng gợi ý)?

Biên tập:

1) chỉ số không gian tồn tại trên các nút bavaria:

CREATE INDEX idx_nodes_geom ON bavaria.nodes USING gist (geom);

2) kế hoạch truy vấn trông như thế này:

HashAggregate  (cost=284908.49..284908.75 rows=26 width=103)
  ->  Nested Loop  (cost=111.27..283900.80 rows=201537 width=103)
        ->  Bitmap Heap Scan on relpolygons relpoly  (cost=4.48..102.29 rows=26 width=5886)
              Recheck Cond: (tags @> '"boundary"=>"administrative", "admin_level"=>"6"'::hstore)
              ->  Bitmap Index Scan on relpolygons_geom_tags  (cost=0.00..4.47 rows=26 width=0)
                    Index Cond: (tags @> '"boundary"=>"administrative", "admin_level"=>"6"'::hstore)
        ->  Bitmap Heap Scan on nodes node  (cost=106.79..10905.50 rows=983 width=127)
              Recheck Cond: (relpoly.geom && geom)
              Filter: _st_intersects(relpoly.geom, geom)
              ->  Bitmap Index Scan on idx_nodes_geom  (cost=0.00..106.55 rows=2950 width=0)
                    Index Cond: (relpoly.geom && geom)

3)

Tôi đã tạo hai chỉ mục sau, nhưng kế hoạch truy vấn (và thời gian chạy) không thay đổi

CREATE INDEX relpolygons_tags_boundary on bavaria.relpolygons( (tags->'boundary') );
CREATE INDEX relpolygons_tags_admin on bavaria.relpolygons( (tags->'admin_level') );
ANALYZE bavaria.relpolygons;

1
Bạn có chỉ số không gian trong bavaria.nodes?
dùng49584

có, tôi đã chỉnh sửa câu hỏi và cung cấp thông tin về chỉ mục trên các nút và kế hoạch truy vấn
Alf Kortig

3
Hai lựa chọn. 1 - thêm một chỉ mục cho các thẻ hstore. 2 - trích xuất các thẻ bạn đang sử dụng cho truy vấn của bạn ( boundaryadmin_level) thành các cột bổ sung trên bảng và sử dụng trực tiếp các thẻ đó.
BradHards

Xem chỉnh sửa (3): hai chỉ mục đã được thêm, nhưng không có thay đổi đối với kế hoạch truy vấn cũng như thời gian chạy.
Alf Kortig 27/1/2015

Sau một số thử nghiệm, tôi không chắc liệu tôi có tạo được các chỉ mục chính xác trong (3) không. Cho đến nay, tôi đã quản lý để tạo một chỉ mục cho -> và? điều hành cửa hàng. Tuy nhiên, tôi đang sử dụng @> trong truy vấn của mình
Alf Kortig

Câu trả lời:


5

Cách tốt nhất để lập chỉ mục các thẻ hstore là sử dụng các chỉ mục GIN hoặc GIST, từ các tài liệu , hỗ trợ @>,?,? & Và? | toán tử , nghĩa là tìm kiếm trên các khóa và cặp khóa / giá trị. Cách tiếp cận của bạn về việc sử dụng hàm để trích xuất các thẻ cho chỉ mục cây B là hợp lý, nhưng vì bạn cũng đang kiểm tra các cặp khóa / giá trị cụ thể, nên bộ phân tích đã chọn quét toàn bộ bảng.

Tôi không có quyền truy cập vào bavaria.relpolygons, nhưng dựa trên một truy vấn tương tự cho OSM UK về giới hạn tốc độ và thẻ đường cao tốc, tôi sẽ giải thích điều này cho câu hỏi sau:

SELECT count(*) 
 FROM ways 
WHERE tags @> 'highway=>motorway'::hstore 
 AND tags @> 'maxspeed=>"50 mph"'::hstore;


Aggregate  (cost=48.66..48.67 rows=1 width=0)
    ->  Index Scan using ix_ways_tags_gist on ways  (cost=0.42..48.64 rows=11 width=0)
     Index Cond: ((tags @> '"highway"=>"motorway"'::hstore) AND (tags @> '"maxspeed"=>"50 mph"'::hstore))

trong đó cho thấy quét chỉ mục trực tiếp (sử dụng chỉ mục chính), cho một bảng có 10 triệu hàng là đáng khích lệ. Chỉ mục được tạo với đơn giản:

CREATE INDEX ix_ways_tags_gist ON ways USING gist (tags);

Mặc dù tôi không thể kiểm tra tình trạng không gian của bạn, tôi đoán nó ít chọn lọc hơn

WHERE relpoly.tags @> '"ranh giới" => "hành chính", "admin_level" => "6"' :: hstore.

và do đó sẽ chỉ được sử dụng cho một điều kiện kiểm tra lại.

Ngoài ra còn có câu trả lời SO tuyệt vời này về sự khác biệt giữa các chỉ số GIN và GIST . Phát hiện chung là các chỉ mục GIN trong khi lớn hơn và chậm hơn để xây dựng, nhanh hơn nhiều về các vấn đề truy xuất văn bản.

Xin lỗi vì trả lời quá muộn, nhưng gần đây tôi đã làm công việc tương tự trên OSM và hstore, và phát hiện ra rằng tôi không chỉ một lần đánh dấu sao câu hỏi này, mà giờ đây tôi có thể trả lời nó: D.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.