STIntersects के प्रदर्शन में सुधार


11

टेबल T_PINमें 300,000 पिन हैं और T_POLYGON36,000 पॉलीगन हैं। T_PINयह सूचकांक है:

CREATE SPATIAL INDEX [T_PIN_COORD] ON [dbo].[T_PIN]
(
[Coord]
)USING  GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY];

T_POLYGON है:

CREATE SPATIAL INDEX [T_POLYGON_COORD] ON [dbo].[T_POLYGON]
(
[COORD]
)USING  GEOGRAPHY_GRID 
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH), 
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
ON [PRIMARY];

के चौराहे को खोजने के लिए एक क्वेरी T_PINऔर T_POLYGONनिष्पादित करने में 45 मिनट से अधिक समय लगता है:

SELECT COUNT(*)
FROM T_PIN 
INNER JOIN T_POLYGON
    ON T_PIN.Coord.STIntersects(T_POLYGON.COORD) = 1;

परिणाम 4,438,318 पंक्तियाँ हैं।

मैं इस क्वेरी को कैसे तेज कर सकता हूं?


क्या आपने `T_POLYGON.Coord.STIntersects (T_PIN.COORD) = 1 'का उपयोग करने का प्रयास किया है?
ट्रैविस

मुझे आपकी क्वेरी योजना देखने में दिलचस्पी होगी। मैं Postgres पर काम करता हूं, लेकिन इसी तरह के प्रश्नों को चलाना है, लेकिन काफी बड़े डेटा सेट पर। मैं एक ऐसी तकनीक के साथ आया हूं जो मेरे सबसे बुरे लोगों को लगभग 2 दिनों तक ले जाती है (जिसमें दुर्भाग्य से स्क्रिप्टिंग शामिल है), लेकिन मैं आपकी क्वेरी योजना को पहले देखना चाहूंगा।
जॉन पॉवेल

पॉलीगनों को मेरी दोनों तालिकाओं में एक साथ गुणा करने पर, मेरे पास एक संख्या है जो संभावित संयोजन की संख्या के मामले में 7000 गुना अधिक है, जितना आपके संयोजन में है, इसलिए मुझे लगता है कि उस प्रकाश में मेरे दो दिन काफी अच्छे लगते हैं। हालांकि, एक क्वेरी योजना को देखे बिना और प्रति बहुभुज की औसत संख्या के बारे में कुछ जानने के बिना, ठोस समाधानों के साथ आना मुश्किल होगा।
जॉन पॉवेल

जवाबों:


7

सबसे पहले, जांचें कि क्वेरी निष्पादन योजना को देखते हुए एक स्थानिक सूचकांक का उपयोग किया जा रहा है या नहीं और देखें कि क्या कोई क्लस्टर इंडेक्स सीक (स्थानिक) आइटम है।

यह माना जा रहा है कि इसका उपयोग किया जा रहा है, आप पहले की जांच करने के लिए सरलीकृत बहुभुज के साथ एक बाउंडिंग बॉक्स के आधार पर एक माध्यमिक / सरलीकृत फ़िल्टर को जोड़ने का प्रयास कर सकते हैं। इन सरलीकृत बहुभुजों के खिलाफ मैच अंतिम परिणाम प्राप्त करने के लिए प्राथमिक फिल्टर के माध्यम से चलाया जा सकता है।

1) [dbo] [T_POLYGON] तालिका में एक नया भूगोल और ज्यामिति कॉलम जोड़ें:

ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeom geometry;
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog geography;

2) बाउंडिंग बॉक्स बहुभुज बनाएं (इसमें स्टीलविलेड () का लाभ उठाने के लिए ज्यामिति के लिए एक प्रारंभिक रूपांतरण शामिल है):

UPDATE [dbo].[T_POLYGON] SET SimplePolysGeom = geometry::STGeomFromWKB(
    COORD.STAsBinary(), COORD.STSrid).STEnvelope();

UPDATE [dbo].[T_POLYGON] SET SimplePolysGeog = geography::STGeomFromWKB(
    SimplePolysGeom.STAsBinary(), SimplePolysGeom.STSrid);

3) सरलीकृत भूगोल कॉलम पर एक स्थानिक सूचकांक बनाएं

4) इस सरलीकृत भूगोल स्तंभ के खिलाफ चौराहों को प्राप्त करें, फिर मिलान भूगोल डेटा प्रकारों पर फिर से फ़िल्टर करें। मोटे तौर पर, कुछ इस तरह:

;WITH cte AS
(
   SELECT pinID, polygonID FROM T_PIN INNER JOIN T_POLYGON
    ON T_PIN.Coord.STIntersects(T_POLYGON.SimplePolysGeog ) = 1
)
SELECT COUNT(*)
FROM T_PIN 
INNER JOIN T_POLYGON
    ON T_PIN.Coord.STIntersects(T_POLYGON.COORD) = 1
    AND T_PIN.pinID IN (SELECT pinID FROM cte)
    AND T_POLYGON.polygonID IN (SELECT polygonID FROM cte)

संपादित करें : आप इस गणना किए गए, स्तंभ के साथ (1) और (2) को प्रतिस्थापित कर सकते हैं। सुझाव के लिए पॉल व्हाइट को श्रेय।

ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS  ([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),[COORD].[STSrid]).STEnvelope().STAsBinary(),(4326))) PERSISTED

हाँ, वह कमोबेश वही है जो मुझे मिल रहा था। मुद्दा जब मैंने पाया है कि एक विस्तृत कवरेज क्षेत्र के साथ तालिका के दो सेटों में "स्थानिक रूप से" शामिल होने का अर्थ यह है कि अनुकूलक अक्सर दो पूर्ण तालिका स्कैन और बहुभुज परीक्षणों में बिंदु के भार के लिए जाता है।
जॉन पॉवेल

2

बहुभुज की जटिलता के कारण इस तरह के प्रश्न अक्सर एक लंबा समय लेते हैं। मैंने जटिल कोस्टलाइन (उदाहरण के लिए) को उन बिंदुओं का परीक्षण करने के लिए उम्र लिया है जो उनकी सीमाओं के पास हैं, यह पता लगाने के लिए कई स्तरों को ज़ूम करना है कि कोई बिंदु अंदर या बाहर है।

... तो आप कोशिश कर सकते हैं .Reduce()'बहुभुज आईएनजी, यह देखने के लिए कि क्या मदद करता है।

और उस फ़ंक्शन के बारे में अधिक जानकारी के लिए, http://msdn.microsoft.com/en-us/library/cc627410.aspx देखें


1

Microsoft डॉक्स के अनुसार, स्थानिक भूगोल के साथ निम्नलिखित तरीकों पर भूगोल प्रकारों का उपयोग किया जाएगा जब वे एक तुलना की शुरुआत में एक WHEREक्लॉज के साथ भविष्यवाणी करते हैं :

  • STIntersects
  • STDistance
  • STEquals

केवल ज्यामिति प्रकार के तरीके (प्रतिबंधित सूची) में स्थानिक सूचकांक के उपयोग को ट्रिगर किया जाएगा JOIN ... ON, इसलिए उपयोग करने के लिए अपने कोड को बदलें WHERE geog1.STIntersects(geog2) = 1और इससे गति में सुधार होना चाहिए।

मैं g2server के उत्तर में सलाह लेने की भी सलाह देता हूं और फ़िल्टर करने के लिए निम्नलिखित जोड़ें और उस पर स्थानिक सूचकांक जोड़ें

ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
     ([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
                                                           [COORD].[STSrid])
                 .STEnvelope().STAsBinary(),(4326))) PERSISTED

फिर आप निम्नलिखित की तरह एक क्वेरी कर सकते हैं (मैंने इस पोस्ट को जल्दी से लिखा है और अभी तक परीक्षण नहीं किया है, यह सिर्फ कोशिश करने के लिए कुछ है क्योंकि मैंने देखा कि आपकी क्वेरी और उच्चतम पोस्ट किए गए उत्तर का उपयोग करें पर स्थानिक ऑप = 1 का उपयोग करें जो कि एक का उपयोग नहीं करेगा स्थानिक सूचकांक):

SELECT   
     (SELECT p2.polygon_id
      FROM   T_Polygon p2
      WHERE  p2.coords.STIntersects(t.coords) = 1),
     t.pin_id
FROM     T_PIN t
WHERE    
     (SELECT t.coords.STIntersects(p.coords)
      FROM   T_POLYGON p
      WHERE  t.coords.STIntersects(p.SimplePolysGeog) = 1) = 1

FYI करें: यदि SimplePolysGeogओवरलैपिंग समाप्त नहीं होती है तो ऊपर काम नहीं करता है (जैसे कि एक पिन दो सरलीकृत जियोगे में हो सकता है, बस इसे एक राज्य में लोगों के लिए प्रचलित तरीके से चलाया जाता है और चूंकि सामान्य पोल शेयर सीमा होती है, इसलिए बाउंडिंग बॉक्स ओवरलैप हो जाते हैं), इसलिए अधिकांश उपयोग में मामलों में, यह एक त्रुटि फेंक देगा कि उपशम एक से अधिक परिणाम लौटाए।

एमएस डॉक्स से स्थानिक सूचकांक अवलोकन :

स्थानिक सूचियों द्वारा समर्थित भूगोल विधियाँ

कुछ शर्तों के तहत, स्थानिक सूचकांक निम्नलिखित सेट-उन्मुख भूगोल विधियों का समर्थन करते हैं: STIntersects (), STEquals (), और STDistance ()। स्थानिक सूचकांक द्वारा समर्थित होने के लिए, इन विधियों का उपयोग किसी क्वेरी के WHERE क्लॉज़ के भीतर किया जाना चाहिए, और उन्हें निम्न सामान्य रूप के एक विधेय के भीतर होना चाहिए:

geography1.method_name (geography2) comparison_operatorvalid_number

गैर-शून्य परिणाम वापस करने के लिए, भूगोल 1 और भूगोल 2 में समान स्थानिक संदर्भ पहचानकर्ता (SRID) होना चाहिए । अन्यथा, विधि NULL देता है।

स्थानिक सूचकांक निम्नलिखित विधेय रूपों का समर्थन करते हैं:


क्वेरीज़ जो स्थानिक अनुक्रमित का उपयोग करती हैं

स्थानिक इंडेक्स केवल उन प्रश्नों में समर्थित होते हैं जिनमें WHERE क्लॉज में एक अनुक्रमित स्थानिक ऑपरेटर शामिल होता है। उदाहरण के लिए वाक्य रचना जैसे:

[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]

क्वेरी ऑप्टिमाइज़र स्थानिक संचालन (कि @a.STIntersects(@b) = @b.STInterestcs(@a)) की कम्यूटिटी को समझता है । हालांकि, स्थानिक सूचकांक का उपयोग नहीं किया जाएगा यदि तुलना की शुरुआत में स्थानिक ऑपरेटर शामिल नहीं है (उदाहरण के WHERE 1 = spatial opलिए स्थानिक सूचकांक का उपयोग नहीं करेगा)। स्थानिक सूचकांक का उपयोग करने के लिए, तुलना (उदाहरण के लिए WHERE spatial op = 1) को फिर से लिखें ।

...

SimplePolysGeogsओवरलैप होने पर निम्नलिखित क्वेरी काम करेगी :

;WITH cte AS
(
   SELECT T_PIN.PIN_ID, 
          T_POLYGON.POLYGON_ID, 
          T_POLYGON.COORD 
   FROM T_PIN 
   INNER JOIN T_POLYGON
   ON T_PIN.COORD.STIntersects(T_POLYGON.SimplePolysGeog) = 1
)

SELECT COUNT(*)
FROM T_PIN 
INNER JOIN cte
ON T_PIN_PIN_ID = cte.PIN_ID
where cte.[COORD].STIntersects(T_PIN.COORD) = 1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.