Първо няколко коментара...
Виждал съм десетки (не милиони) внедряване тук и в други форуми; твоят е по-добър от повечето.
Според един източник на данни (който случайно съм изтеглил) в света има около 3,2 милиона града.
За ефективност трябва да избягвате да проверявате всички 3M редове. Направихте добър старт с нарастващата ограничителна кутия. Имайте предвид, че трябва да имате
INDEX(lat, lon),
INDEX(lon, lat)
Оптимизаторът ще избере между тези и първата заявка (с COUNT(*)
) ще види това като „покриване“. Ще бъде ивица около земното кълбо или клин; определено подобрение спрямо 3M реда. На най-лошата географска ширина (+34 градуса) има 96 хиляди града. (1 градус =69 мили / 111 км.) За една десета от градуса 34,4 е най-лошото, с 10 000 града.
(Да, харесвам този вид пъзел с данни.)
И виждам, че се справяте с линията на датата и полюсите. Не мисля, че можете да подобрите, като ги имате като специален случай.
(Погледнах само формулите и константите.)
Geohash и индексирането на Z-порядък помагат. Но те имат проблем в това, че трябва да проверите до 4 области около целта -- Все едно да не осъзнавате, че цели числа 199999 и 200000 са наистина близки едно до друго, въпреки че първата цифра на всяка е различна.
„Потребителят предава пощенски код или име на град“ – това е точкова заявка в една от двете прости таблици. (С изключение на това, че може да има дупки – над 320 всеки от „сан хосе“ и „сан антонио“. Доста по-надолу в списъка е първото неиспанско име:„виктория“, само със 144 града.)
Второ, моята реализация... (Има някои прилики с вашия.)
http://mysql.rjweb.org/doc.php/latlng
Това подобрява производителността чрез използване на PARTITIONing
за поддържане на ограничителната кутия надолу до приблизително квадрат, вместо ивица или клин. Ако търсите 5-те най-близки, моят алгоритъм рядко ще докосне повече от няколко десетки реда и тези редове ще бъдат „групирани“ в малък брой блокове, като по този начин броят на посещенията на диска ще бъде много нисък.
Критично нещо в моя дизайн е да имам всички необходими колони в една таблица. След като намерите най-близките 5, можете да отидете на други маси, за да получите допълнителни неща (телефонен номер и т.н.).
Що се отнася до пощенските кодове, превърнете ги в широта/долна дължина, преди да започнете да търсите 5-те най-близки.
Обединяването в алгоритъма е много вероятно да унищожи производителността.