दुर्भाग्य से ST_Distance() < threshold
sargable
नहीं है खोज मानदंड। इस क्वेरी को संतुष्ट करने के लिए, MySQL को तालिका में प्रत्येक पंक्ति के लिए फ़ंक्शन के मान की गणना करनी चाहिए, और फिर इसकी तुलना थ्रेशोल्ड से करनी चाहिए। तो इसे एक पूर्ण तालिका स्कैन (या शायद एक पूर्ण अनुक्रमणिका स्कैन) करना होगा।
इस क्वेरी को तेज़ करने के लिए एक इंडेक्स का फायदा उठाने के लिए, आपको एक बाउंडिंग-बॉक्स मानदंड की आवश्यकता होगी। क्वेरी बहुत अधिक विस्तृत है, लेकिन बहुत तेज़ भी है। यह मानते हुए कि आपकी ज्यामिति में आपके x/y अंक डिग्री में अक्षांश/देशांतर का प्रतिनिधित्व करते हैं, वह क्वेरी इस तरह दिख सकती है:
set @latpoint = 38.0234332;
set @lngpoint = -94.0724223;
set @r = 10.0; /* ten mile radius */
set @units=69.0; /* 69 statute miles per degree */
SELECT AsText(geo)
FROM markers
WHERE MbrContains(GeomFromText(
CONCAT('LINESTRING(', @latpoint-(@r/@units),' ',
@lngpoint-(@r /(@units* COS(RADIANS(@latpoint)))),
',',
@latpoint+(@r/@units) ,' ',
@lngpoint+(@r /(@units * COS(RADIANS(@latpoint)))),
')')),
geo)
यह कैसे काम करता है? एक बात के लिए, MbrContains( बाउंड, आइटम) फ़ंक्शन है sargable . एक और बात के लिए, बड़ा बदसूरत कॉनकैट आइटम दक्षिण-पश्चिम से बाउंडिंग आयत के उत्तर-पूर्व कोने तक एक विकर्ण रेखा उत्पन्न करता है। अपने डेटा बिंदु और दस मील के दायरे का उपयोग करके यह ऐसा दिखता है।
LINESTRING(37.8785 -94.2564,38.1684 -93.8884)
जब आप GeomFromText()
. का उपयोग करते हैं MbrContains()
. के पहले तर्क में उस विकर्ण रेखा का प्रतिपादन यह एक बाउंडिंग आयत के रूप में कार्य करता है। MbrContains()
फिर निफ्टी क्वाडट्री ज्योमेट्री इंडेक्स का फायदा उठा सकते हैं।
तीसरा, ST_Distance()
, MySQL में, महान वृत्त अक्षांश और देशांतर गणनाओं को संभालता नहीं है। (PostgreSQL
अधिक व्यापक GIS एक्सटेंशन
है .) MySQL फ्लैटलैंड में फ्लैपजैक की तरह गूंगा है। यह मानता है कि आपके ज्यामितीय वस्तुओं में आपके अंक प्लेनर ज्यामिति में दर्शाए गए हैं। तो ST_Distance() < 10.0
lng/lat अंक के साथ कुछ अजीब होता है।
इस क्वेरी द्वारा उत्पन्न परिणामों में एक दोष है; यह बाउंडिंग बॉक्स में सभी बिंदुओं को लौटाता है, न कि केवल निर्दिष्ट दायरे के भीतर। यह एक अलग दूरी गणना के साथ हल करने योग्य है। मैंने यह सब यहां कुछ विस्तार से लिखा हैए> ।
नोट :GPS-रिज़ॉल्यूशन अक्षांश और देशांतर के लिए, 32-बिट FLOAT
डेटा में पर्याप्त सटीकता है। DOUBLE
वह है जो MySQL का जियो एक्सटेंशन उपयोग करता है। जब आप डिग्री में काम कर रहे होते हैं, तो दशमलव बिंदु के बाद पांच से अधिक स्थान GPS की सटीकता से परे होते हैं। DECIMAL()
lat/lng निर्देशांकों के लिए आदर्श डेटाटाइप नहीं है।