पहले कुछ टिप्पणियां...
मैंने यहां और अन्य मंचों पर कार्यान्वयन के दर्जनों (लाखों नहीं) देखे हैं; तुम्हारा सबसे बेहतर है।
एक डेटा स्रोत के अनुसार (जो मैंने डाउनलोड किया है) दुनिया में लगभग 3.2 मिलियन शहर हैं।
प्रदर्शन के लिए, आपको सभी 3M पंक्तियों की जाँच करने से बचना होगा। आपने बढ़ते बाउंडिंग बॉक्स के साथ अच्छी शुरुआत की है। ध्यान दें कि आपके पास होना चाहिए
INDEX(lat, lon),
INDEX(lon, lat)
अनुकूलक उन और पहली क्वेरी के बीच चयन करेगा (COUNT(*)
. के साथ ) इसे 'कवर' के रूप में देखेंगे। यह दुनिया भर में एक पट्टी या एक कील होगी; 3M पंक्तियों में एक निश्चित सुधार। सबसे खराब अक्षांश (+34 डिग्री) में 96K शहर हैं। (1 डिग्री =69 मील / 111 किमी।) डिग्री के दसवें हिस्से के लिए, 10K शहरों के साथ, 34.4 सबसे खराब है।
(हां, मैं इस तरह की डेटा पहेली का आनंद लेता हूं।)
और, मैं देख रहा हूं कि आप डेटलाइन और डंडे को संभालते हैं। मुझे नहीं लगता कि आप उन्हें एक विशेष मामले के रूप में रखने में सुधार कर सकते हैं।
(मैंने केवल सूत्रों और स्थिरांक पर ध्यान दिया है।)
जियोहाश और जेड-ऑर्डर इंडेक्सिंग मदद करते हैं। लेकिन उनमें एक समस्या यह है कि आपको लक्ष्य के आस-पास के 4 क्षेत्रों की जांच करने की आवश्यकता है -- यह ऐसा महसूस नहीं करने जैसा है कि पूर्णांक 1999999 और 200000 वास्तव में एक दूसरे के करीब हैं, प्रत्येक का पहला अंक अलग होने के बावजूद।पी>
"उपयोगकर्ता ज़िप कोड या शहर के नाम में गुजरता है" - यह दो साधारण तालिकाओं में से एक में एक बिंदु क्वेरी है। (सिवाय इसके कि डुप्स हो सकते हैं - "सैन जोस" और "सैन एंटोनियो" में से प्रत्येक में 320 से अधिक। सूची में बहुत नीचे पहला गैर-स्पैनिश नाम है:"विक्टोरिया", केवल 144 शहरों के साथ।)
दूसरा, मेरा कार्यान्वयन... (इसमें आपकी कुछ समानताएं हैं।)
http://mysql.rjweb.org/doc.php/latlng
यह PARTITIONing
. का उपयोग करके प्रदर्शन में सुधार करता है बाउंडिंग बॉक्स को स्ट्राइप या वेज के बजाय मोटे तौर पर एक वर्ग के नीचे रखने के लिए। यदि आप 5 निकटतम की तलाश कर रहे हैं, तो मेरा एल्गोरिथ्म शायद ही कभी कुछ दर्जन से अधिक पंक्तियों को स्पर्श करेगा, और उन पंक्तियों को कम संख्या में ब्लॉक में 'क्लस्टर' किया जाएगा, जिससे डिस्क हिट की संख्या बहुत कम रहेगी।
मेरे डिजाइन में एक महत्वपूर्ण बात यह है कि एक ही टेबल में सभी आवश्यक कॉलम हों। एक बार जब आपको निकटतम 5 मिल जाए, तो आप सहायक चीजें (फोन नंबर, आदि) प्राप्त करने के लिए अन्य तालिकाओं पर जा सकते हैं।
जहां तक ज़िप कोड की बात है, तो निकटतम 5 की खोज शुरू करने से पहले उन्हें lat/lon में बदल दें।
एल्गोरिथम के अंदर एक जुड़ाव प्रदर्शन को नष्ट करने की बहुत संभावना है।