Nejprve několik komentářů...
Viděl jsem desítky (ne miliony) implementací zde a na jiných fórech; tvoje je lepší než většina.
Podle jednoho zdroje dat (který jsem si náhodou stáhl) je na světě asi 3,2 milionu měst.
Pro výkon se musíte vyhnout kontrole všech 3M řádků. S rostoucím ohraničujícím boxem jste začali dobře. Všimněte si, že byste měli mít
INDEX(lat, lon),
INDEX(lon, lat)
Optimalizátor vybere mezi těmito a prvním dotazem (s COUNT(*)
). ) to uvidí jako „pokrývající“. Bude to pruh kolem zeměkoule nebo klín; jednoznačné zlepšení oproti 3M řádkům. Nejhorší zeměpisná šířka (+34 stupňů) má 96 tisíc měst. (1 stupeň =69 mil / 111 km.) Pro desetinu stupně je nejhorší 34,4 s 10 000 městy.
(Ano, tento druh datové hádanky mě baví.)
A vidím, že zvládáte datovou čáru a póly. Nemyslím si, že byste je mohli zlepšit tím, že je budete mít jako speciální případ.
(Pouze jsem se podíval na vzorce a konstanty.)
Geohash a indexování Z-order pomáhají. Ale mají škytavku v tom, že musíte zkontrolovat až 4 oblasti kolem cíle -- Je to jako neuvědomovat si, že celá čísla 199999 a 200000 jsou opravdu blízko sebe, přestože první číslice každého z nich je jiná.
„Uživatel zadá PSČ nebo název města“ – to je bodový dotaz do jedné ze dvou jednoduchých tabulek. (Až na to, že mohou existovat dupy -- více než 320 každý z „san jose“ a „san antonio“. Poměrně hluboko v seznamu je první nešpanělské jméno:„victoria“ s pouze 144 městy.)
Zadruhé, moje implementace... (Má určité podobnosti s vaším.)
http://mysql.rjweb.org/doc.php/latlng
To zlepšuje výkon pomocí PARTITIONing
k udržení ohraničovacího rámečku zhruba do čtverce místo pruhu nebo klínu. Pokud hledáte 5 nejbližších, můj algoritmus se zřídka dotkne více než několika desítek řádků a tyto řádky budou „seskupeny“ do malého počtu bloků, čímž bude počet zásahů na disk velmi nízký.
Rozhodující věcí v mém návrhu je mít všechny potřebné sloupce v jedné tabulce. Jakmile najdete nejbližších 5, můžete přejít k dalším stolům a získat doplňkové věci (telefonní číslo atd.).
Pokud jde o PSČ, změňte je na zeměpisnou šířku a délku, než začnete hledat 5 nejbližších.
Spojení uvnitř algoritmu velmi pravděpodobně zničí výkon.