क्यों st_intersects && से अधिक तेज़ है


10

यह अंकों की तालिका है। ~ 1M रिकॉर्ड

SELECT COUNT(*) as value FROM alasarr_social_mv s; 
Output: 976270

यह स्थानिक अनुक्रमित का उपयोग करने के लिए st_intersects बलों की तरह दिखता है, लेकिन && नहीं करता है।

नमूना ST_Intersects(282ms) का उपयोग करना

SELECT COUNT(*) as value
FROM alasarr_social_mv 
WHERE ST_Intersects(
  the_geom_webmercator, 
  ST_MakeEnvelope(-410961,4920492,-402305,4926887,3857)
)


Aggregate  (cost=34370.18..34370.19 rows=1 width=0) (actual time=282.715..282.715 rows=1 loops=1)
  ->  Bitmap Heap Scan on alasarr_social_mv s  (cost=5572.17..34339.84 rows=60683 width=0) (actual time=21.574..240.195 rows=178010 loops=1)
        Recheck Cond: (the_geom_webmercator && '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
        Filter: _st_intersects(the_geom_webmercator, '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
        Heap Blocks: exact=4848
        ->  Bitmap Index Scan on alasarr_social_mv_gix  (cost=0.00..5569.13 rows=182050 width=0) (actual time=20.836..20.836 rows=178010 loops=1)
              Index Cond: (the_geom_webmercator && '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
Planning time: 0.192 ms
Execution time: 282.758 ms

नमूना का उपयोग कर &&(414ms)

SELECT COUNT(*) as value
FROM alasarr_social_mv  
WHERE the_geom_webmercator && 
  ST_MakeEnvelope(-410961,4920492,-402305,4926887,3857)

Aggregate  (cost=22535.97..22535.97 rows=1 width=0) (actual time=414.314..414.314 rows=1 loops=1)
  ->  Seq Scan on alasarr_social_mv  (cost=0.00..22444.94 rows=182050 width=0) (actual time=0.017..378.427 rows=178010 loops=1)
        Filter: (the_geom_webmercator && '0103000020110F0000010000000500000000000000441519C1000000002BC5524100000000441519C1000000C069CB524100000000048E18C1000000C069CB524100000000048E18C1000000002BC5524100000000441519C1000000002BC55241'::geometry)
        Rows Removed by Filter: 798260
Planning time: 0.134 ms
Execution time: 414.343 ms

PostGIS संस्करण

POSTGIS="2.2.2" GEOS="3.5.0-CAPI-1.9.0 r4084" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.11.0, released 2014/04/16" LIBXML="2.7.8" LIBJSON="UNKNOWN" (core procs from "2.2.2" need upgrade) RASTER (raster procs from "2.2.2" need upgrade)  alasarr 2 mins ago

2
प्रश्न में पाठ के स्क्रीन शॉट्स पेस्ट न करें। क्या आप उन्हें कोड के रूप में कॉपी और पेस्ट कर सकते हैं? मैं आपकी मदद करने के लिए उन्हें नहीं पढ़ सकता।
इवान कैरोल

किया हुआ। मुझे लगता है कि अब थोड़ा बेहतर है
alasarr

मैंने आपकी नई क्वेरी योजनाओं को उसमें वापस लाने की कोशिश की। योजनाओं को उन्नत करने के लिए स्वतंत्र महसूस करें लेकिन शैली को बनाए रखने की कोशिश करें।
इवान कैरोल

4
इस सवाल पर एक नजर । && ऑपरेटर वास्तव में एक बाउंडिंग बॉक्स क्वेरी करता है, जबकि, ST_Intersects वास्तविक तुलना के लिए कौन से ज्यामिति का परीक्षण करते हैं, यह निर्धारित करने के लिए एक बाउंडिंग बॉक्स क्वेरी का उपयोग करता है - इसलिए आप अपेक्षा करेंगे कि && जल्दी हो। हालाँकि, यह संभावना है कि && के दाईं ओर ST_MakeEnvelope का उपयोग क्वेरी प्लानर को किसी कारण के लिए पूर्ण तालिका स्कैन चुना गया है (जैसा कि स्पष्ट से स्पष्ट है)। पहले ज्यामिति बनाने की कोशिश करें, एक सीटीई में, और देखें कि क्या आप अनुकूलक को "मूर्ख" कर सकते हैं।
जॉन पॉवेल

आप सही हे! यह एक CTE के अंदर काम करता है
alasarr

जवाबों:


16

इस तरह की खोज काफी बार सामने आती है, और यह थोड़ा अस्पष्ट है, इसलिए आराम करने लायक है। यदि आप एक फ़ंक्शन के भीतर एक ज्यामिति को परिभाषित करते हैं जो इसका उपयोग करता है, जैसे ST_Intersects या && (जो ST_Intersects हुड के तहत उपयोग करता है), तो क्वेरी प्लानर एक पूर्ण तालिका स्कैन चुनता है, क्योंकि "इसे" में ज्यामिति निर्माण के परिणाम का कोई ज्ञान नहीं है फ़ंक्शन, यानी, इस मामले में ST_MakeEnvelope .. यदि आप उस ज्यामिति को परिभाषित करते हैं जिसे आप CTE में प्रतिच्छेदन के लिए जांचना चाहते हैं, तो ऑप्टिमाइज़र एक ज्ञात मात्रा के साथ काम कर रहा है, और यदि उपलब्ध हो तो एक स्थानिक सूचकांक का उपयोग करेगा।

इसलिए, अपनी क्वेरी को इस प्रकार लिखें:

WITH test_geom (geom) AS 
   (SELECT ST_MakeEnvelope(-410961,4920492,-402305,4926887,3857))
  SELECT COUNT(*) as value
    FROM alasarr_social_mv mv, test_geom tg 
   WHERE ST_Intersects(mv.the_geom_webmercator, tg.geom)

अब एक स्थानिक सूचकांक का उपयोग करेगा। इसी तरह, && अब एक बाउंडिंग बॉक्स की जांच के लिए एक इंडेक्स का उपयोग करेगा, और (जबकि मैं आपके डेटा के खिलाफ परीक्षण नहीं कर सकता), ST_Intersects की तुलना में तेज़ होना चाहिए।

दिलचस्प बात यह है कि, आपकी क्वेरी में, ST_Intersects बिटमैप स्कैन (gist नहीं) इंडेक्स का उपयोग कर रहा है, जबकि && इस इंडेक्स का उपयोग कर रहा है। तो, CTE के साथ दोनों क्विक क्विकर जल्दी हो जाएंगे, लेकिन && अब ST_Intersects की तुलना में तेज होना चाहिए।

इस प्रश्न और इसके उत्तर / टिप्पणियों पर क्या चल रहा है, इसकी अधिक व्याख्या है ।

EDIT : इसे स्पष्ट करने के लिए, यदि आप postgis.sql में ST_Intersects की परिभाषा को देखते हैं (जिसे CREATE EXTENSION postgisआपके पोस्टग्रैस इंस्टाल के कंट्रीब्यूट डायरेक्टरी में कहा जाता है और पाया जाता है ), आप देखेंगे:

---- Inlines index magic
CREATE OR REPLACE FUNCTION ST_Intersects(geom1 geometry, geom2 geometry)
    RETURNS boolean
    AS 'SELECT $1 OPERATOR(&&) $2 AND _ST_Intersects($1,$2)'
    LANGUAGE 'sql' IMMUTABLE ;

टिप्पणी सहित: इनलाइन सूचकांक जादू।


1
मुझे नहीं लगता कि हुड के नीचे ST_Intersects && का उपयोग करता है।
इवान कैरोल

4
@EvanCarroll, मेरे संपादन की जाँच करें। Postgis.sql पर एक नज़र डालें, जहां फ़ंक्शन परिभाषित हैं, और यह स्पष्ट होना चाहिए।
जॉन पॉवेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.