यह प्रश्न बहुत आगे तक जाना चाहिए (बहुत होना चाहिए) तेज़):
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;
यह नहीं है आपकी मूल क्वेरी के समान, बल्कि आप वास्तव में क्या चाहते हैं, टिप्पणियों में चर्चा के अनुसार :
तो यह क्वेरी उन स्कूलों की सूची लौटाती है, उसके बाद पास के बार और रेस्तरां हैं। पंक्तियों के प्रत्येक सेट को osm_id
. द्वारा एक साथ रखा जाता है कॉलम में स्कूल का school_id
.
अब LATERAL
का उपयोग कर रहे हैं जॉइन करता है, स्थानिक जिस्ट इंडेक्स का उपयोग करने के लिए।
TABLE school
SELECT * FROM school
. के लिए बस शॉर्टहैंड है :
व्यंजक (type <> 'school')
पहले प्रत्येक सेट में स्कूल को आदेश दें, क्योंकि:
सबक्वेरी sub
फाइनल में SELECT
केवल इस अभिव्यक्ति द्वारा आदेश देने की आवश्यकता है। एक UNION
क्वेरी संलग्न ORDER BY
. को सीमित करती है केवल कॉलम की सूची, कोई भाव नहीं।
मैं इस उत्तर के उद्देश्य के लिए आपके द्वारा प्रस्तुत प्रश्न पर ध्यान केंद्रित करता हूं - अनदेखा करना अन्य 70 टेक्स्ट कॉलम में से किसी पर फ़िल्टर करने की विस्तारित आवश्यकता। यह वास्तव में एक डिजाइन दोष है। खोज मानदंड कुछ . में केंद्रित होना चाहिए स्तंभ। या आपको सभी 70 स्तंभों को अनुक्रमित करना होगा, और बहुस्तंभ अनुक्रमणिका जैसे मैं प्रस्तावित करने जा रहा हूँ शायद ही कोई विकल्प हो। अभी भी संभव हालांकि ...
सूचकांक
मौजूदा के अलावा:
"idx_planet_osm_point_waygeo" gist (way_geo)
यदि हमेशा एक ही कॉलम पर फ़िल्टरिंग करते हैं, तो आप एक बना सकते हैं। बहुस्तंभ अनुक्रमणिका आपकी रुचि के कुछ कॉलम को कवर करता है, इसलिए index- केवल स्कैन करता है संभव हो जाना:
CREATE INDEX planet_osm_point_bar_idx ON planet_osm_point (amenity, name, osm_id)
पोस्टग्रेज 9.5
आगामी पोस्टग्रेज 9.5 पेश करता है प्रमुख सुधार जो आपके मामले को ठीक से संबोधित करने के लिए होता है:
यह आपके लिए विशेष रुचि का है। अब आपके पास एकल . हो सकता है बहुस्तंभ (कवर) जिस्ट सूचकांक:
CREATE INDEX reservations_range_idx ON reservations
USING gist(amenity, way_geo, name, osm_id)
और:
और:
क्यों? क्योंकि ROLLUP
कोड>
मेरे द्वारा सुझाई गई क्वेरी को सरल बना देगा। संबंधित उत्तर:
पहला अल्फा संस्करण 2 जुलाई 2015 को जारी किया गया है। रिलीज के लिए अपेक्षित समयरेखा:
मूल बातें
बेशक, मूलभूत बातों को नज़रअंदाज़ न करना सुनिश्चित करें: