Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL:come eseguire una query sull'intervallo IP più veloce? GeoIP

Avevo a che fare con un problema simile, in cui dovevo cercare in un database con circa 4 milioni di intervalli di IP e ho trovato una buona soluzione che ha ridotto il numero di righe scansionate da 4 milioni a circa ~5 (a seconda dell'IP):

Questa istruzione SQL:

SELECT id FROM geoip WHERE $iplong BETWEEN range_begin AND range_end 

viene trasformato in:

SELECT id FROM geoip WHERE range_begin <= $iplong AND range_end >= $iplong 

Il problema è che MySQL recupera tutte le righe con 'range_begin <=$iplong' e quindi deve scansionare se 'range_end>=$iplong'. Questa prima condizione AND (range_begin <=$iplong) ha recuperato circa 2 milioni di righe e tutte devono essere verificate se range_end corrisponde.

Questo tuttavia può essere notevolmente semplificato aggiungendo una condizione AND:

SELECT id FROM geoip WHERE range_begin <= $iplong AND range_begin >= $iplong-65535 AND range_end >= $iplong 

La dichiarazione

range_begin <= $iplong AND range_begin >= $iplong-65535

recupera solo le voci in cui range_begin è compreso tra $ iplong-65535 e $ iplong. Nel mio caso, questo ha ridotto il numero di righe recuperate da 4 milioni. a circa 5 e il runtime dello script è passato da più minuti a pochi secondi.

Nota su 65535 :Questa è per la mia tabella la distanza massima tra range_begin e range_end, ovvero (range_end-range_begin) <=65535 per tutte le mie righe. Se hai intervalli IP più grandi, devi aumentare il 65535, se hai intervalli IP più piccoli, puoi diminuire questa costante. Se questa costante è troppo grande (ad esempio 4 miliardi), non risparmierai tempo di query.

Per questa query, hai solo bisogno di un indice su range_begin.