Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL:Jak wykonać szybsze zapytanie o zakres adresów IP? GeoIP

Miałem do czynienia z podobnym problemem, gdzie musiałem przeszukać bazę danych z około 4 milionami zakresów adresów IP i znalazłem fajne rozwiązanie, które zmniejszyło liczbę skanowanych wierszy z 4 milionów do około ~5 (w zależności od IP):

Ta instrukcja SQL:

SELECT id FROM geoip WHERE $iplong BETWEEN range_begin AND range_end 

przekształca się w:

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

Problem polega na tym, że MySQL pobiera wszystkie wiersze z 'range_begin <=$iplong', a następnie musi przeskanować, czy 'range_end>=$iplong'. Ten pierwszy warunek ORAZ (range_begin <=$iplong) pobrał około 2 miliony wierszy i wszystkie należy sprawdzić, jeśli pasuje do range_end.

Można to jednak radykalnie uprościć, dodając jeden warunek AND:

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

Oświadczenie

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

pobiera tylko wpisy, w których range_begin mieści się w zakresie od $iplong-65535 do $iplong. W moim przypadku zmniejszyło to liczbę pobranych wierszy z 4 mln. do około 5, a czas działania skryptu skrócił się z kilku minut do kilku sekund.

Uwaga na temat 65535 :To jest dla mojej tabeli maksymalna odległość między range_begin i range_end, tj. (range_end-range_begin) <=65535 dla wszystkich moich wierszy. Jeśli masz większe zakresy adresów IP, musisz zwiększyć 65535, jeśli masz mniejsze zakresy adresów IP, możesz zmniejszyć tę stałą. Jeśli ta stała jest zbyt duża (na przykład 4 miliardy), nie zaoszczędzisz czasu na zapytania.

Dla tego zapytania potrzebujesz tylko indeksu na range_begin.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Szukasz prostego wyszukiwania pełnotekstowego? Wypróbuj MySQL InnoDB + CakePHP z Word Stemming

  2. Jak przechowywać znaki inne niż angielskie?

  3. Jak mogę wstawić dane NULL do bazy danych MySQL za pomocą Pythona?

  4. Ograniczanie połączeń MySQL z hosta lokalnego w celu poprawy bezpieczeństwa

  5. Muszę zmienić format daty za pomocą php