PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

धीमी गति से प्रदर्शन करते हुए कई सेल्फ जॉइन के साथ बड़ी टेबल पर स्थानिक क्वेरी

यह प्रश्न बहुत आगे तक जाना चाहिए (बहुत होना चाहिए) तेज़):

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 को जारी किया गया है। रिलीज के लिए अपेक्षित समयरेखा:

मूल बातें

बेशक, मूलभूत बातों को नज़रअंदाज़ न करना सुनिश्चित करें:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PgAdmin4 चलाने का प्रयास करने में त्रुटि

  2. कैसे अपने डोकर कंटेनर में psql इंटरैक्टिव निष्पादित करने के लिए?

  3. जॉइन के साथ UNNEST का उपयोग करना

  4. रूबी पीजी रत्न का उपयोग करके तैयार किए गए INSERT कथन का उदाहरण

  5. django.db.utils.OperationalError:सर्वर से कनेक्ट नहीं हो सका:ऐसी कोई फ़ाइल या निर्देशिका नहीं