PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Truy vấn không gian trên bảng lớn với nhiều liên kết tự hoạt động chậm

Truy vấn này sẽ đi một chặng đường dài (được nhiều nhanh hơn):

WITH school AS (
   SELECT s.osm_id AS school_id, text 'school' AS type, s.osm_id, s.name, s.way_geo
   FROM   planet_osm_point s
        , LATERAL (
      SELECT  1 FROM planet_osm_point
      WHERE   ST_DWithin(way_geo, s.way_geo, 500, false)
      AND     amenity = 'bar'
      LIMIT   1  -- bar exists -- most selective first if possible
      ) b
        , LATERAL (
      SELECT  1 FROM planet_osm_point
      WHERE   ST_DWithin(way_geo, s.way_geo, 500, false)
      AND     amenity = 'restaurant'
      LIMIT   1  -- restaurant exists
      ) r
   WHERE  s.amenity = 'school'
   )
SELECT * FROM (
   TABLE school  -- schools

   UNION ALL  -- bars
   SELECT s.school_id, 'bar', x.*
   FROM   school s
        , LATERAL (
      SELECT  osm_id, name, way_geo
      FROM    planet_osm_point
      WHERE   ST_DWithin(way_geo, s.way_geo, 500, false)
      AND     amenity = 'bar'
      ) x

   UNION ALL  -- restaurants
   SELECT s.school_id, 'rest.', x.*
   FROM   school s
        , LATERAL (
      SELECT  osm_id, name, way_geo
      FROM    planet_osm_point
      WHERE   ST_DWithin(way_geo, s.way_geo, 500, false)
      AND     amenity = 'restaurant'
      ) x
   ) sub
ORDER BY school_id, (type <> 'school'), type, osm_id;

Đây là không giống như truy vấn ban đầu của bạn, nhưng đúng hơn là những gì bạn thực sự muốn, theo thảo luận trong nhận xét :

Vì vậy, truy vấn này trả về danh sách các trường đó, theo sau là các quán bar và nhà hàng gần đó. Mỗi nhóm hàng được tổ chức với nhau bằng osm_id của trường trong cột school_id .

Hiện đang sử dụng LATERAL tham gia, để sử dụng chỉ mục GiST không gian.

trường TABLE chỉ là viết tắt của SELECT * FROM school :

Biểu thức (type <> 'school') đặt hàng trường học trong mỗi tập hợp trước, bởi vì:

Truy vấn con sub trong SELECT cuối cùng chỉ cần thiết để sắp xếp theo biểu thức này. Một UNION truy vấn giới hạn ORDER BY đính kèm chỉ liệt kê các cột, không có biểu thức.

Tôi tập trung vào truy vấn bạn đã trình bày cho mục đích của câu trả lời này - bỏ qua yêu cầu mở rộng để lọc trên bất kỳ cột văn bản nào trong số 70 cột văn bản khác. Đó thực sự là một lỗ hổng thiết kế. Tiêu chí tìm kiếm nên được tập trung ở vài cột. Hoặc bạn sẽ phải lập chỉ mục tất cả 70 cột và các chỉ mục đa cột như tôi sắp đề xuất hầu như không phải là một lựa chọn. Vẫn có thể mặc dù ...

Chỉ mục

Ngoài cái hiện có:

"idx_planet_osm_point_waygeo" gist (way_geo)

Nếu luôn lọc trên cùng một cột, bạn có thể tạo chỉ mục nhiều cột bao gồm một số cột mà bạn quan tâm, vì vậy index- chỉ quét trở nên khả thi:

CREATE INDEX planet_osm_point_bar_idx ON planet_osm_point (amenity, name, osm_id)

Postgres 9.5

Postgres sắp ra mắt 9.5 giới thiệu những cải tiến lớn điều đó xảy ra để giải quyết chính xác trường hợp của bạn:

Đó là mối quan tâm đặc biệt cho bạn. Bây giờ bạn có thể có một đĩa đơn chỉ số GiST đa cột (bao trùm):

CREATE INDEX reservations_range_idx ON reservations
USING gist(amenity, way_geo, name, osm_id)

Và:

Và:

Tại sao? Bởi vì ROLLUP sẽ đơn giản hóa truy vấn mà tôi đã đề xuất. Câu trả lời liên quan:

Phiên bản alpha đầu tiên đã được phát hành vào ngày 2 tháng 7 năm 2015. Tiến trình dự kiến ​​cho bản phát hành:

Kiến thức cơ bản

Tất nhiên, hãy chắc chắn không bỏ qua những điều cơ bản:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để chèn dấu thời gian với múi giờ trong postgresql với câu lệnh đã chuẩn bị?

  2. Làm cách nào để xóa dạng xem bảng * hoặc * khỏi cơ sở dữ liệu PostgreSQL?

  3. Giá trị tiếp theo của PostgreSQL của các chuỗi?

  4. lỗi heroku Postgres - toán tử không tồn tại dấu thời gian mà không có múi giờ =số nguyên

  5. Làm cách nào để có được một kết xuất cơ sở dữ liệu postgres văn bản thuần túy trên heroku?