Primero algunos comentarios...
He visto docenas (no millones) de implementaciones aquí y en otros foros; el tuyo es mejor que el de la mayoría.
Según una fuente de datos (que casualmente descargué) hay alrededor de 3,2 millones de ciudades en el mundo.
Para el rendimiento, debe evitar verificar todas las filas de 3M. Ha tenido un buen comienzo con el cuadro delimitador en crecimiento. Tenga en cuenta que debe tener
INDEX(lat, lon),
INDEX(lon, lat)
El Optimizer elegirá entre esas y la primera consulta (con el COUNT(*)
) verá eso como 'cubrir'. Será una franja alrededor del globo o una cuña; una mejora definitiva sobre las filas de 3M. La peor latitud (+34 grados) tiene 96K ciudades. (1 grado =69 millas / 111 km.) Para una décima de grado, 34,4 es lo peor, con 10K ciudades.
(Sí, disfruto este tipo de rompecabezas de datos).
Y veo que usted maneja la línea de fecha y los polos. No creo que puedas mejorar tenerlos como un caso especial.
(Solo he echado un vistazo a las fórmulas y constantes).
Ayuda de indexación de orden Z y Geohash. Pero tienen un inconveniente en el sentido de que debe verificar hasta 4 áreas alrededor del objetivo:es como no darse cuenta de que los números enteros 199999 y 200000 están muy cerca uno del otro, a pesar de que el primer dígito de cada uno es diferente.
"El usuario ingresa el código postal o el nombre de la ciudad":esa es una consulta puntual en una de dos tablas simples. (Excepto que puede haber duplicados:más de 320 de cada uno de "san jose" y "san antonio". Bastante abajo en la lista está el primer nombre no español:"victoria", con solo 144 ciudades).
Segundo, mi implementación... (Tiene algunas similitudes con el tuyo).
http://mysql.rjweb.org/doc.php/latlng
Esto mejora el rendimiento mediante el uso de PARTITIONing
a mantener el cuadro delimitador en aproximadamente un cuadrado, en lugar de una franja o una cuña. Si está buscando las 5 más cercanas, mi algoritmo rara vez tocará más de unas pocas docenas de filas, y esas filas se 'agruparán' en una pequeña cantidad de bloques, lo que mantendrá la cantidad de accesos al disco muy baja.
Una cosa crítica en mi diseño es tener todas las columnas necesarias en una tabla. Una vez que haya encontrado los 5 más cercanos, puede ir a otras mesas para obtener cosas auxiliares (número de teléfono, etc.).
En cuanto a los códigos postales, conviértalos en latitud/longitud antes de iniciar la búsqueda de los 5 más cercanos.
Es muy probable que una combinación dentro del algoritmo destruya el rendimiento.