Avatar billede kgp43 Nybegynder
26. april 2006 - 20:04 Der er 14 kommentarer og
1 løsning

optimering af query

Hejsa,

Jeg har følgende query den konvertere IP på mine brugere til "country code".

Problemet er bare at jeg har 175,000 brugere og "geo-ip" tabellen har ca 50,000 rækker - så koden tager for lang tid og får serveren til at gå ned.

hvad kan jeg gøre for at optimere den?


///////////////////////////////////////////////////

// Get accounts
$query = mysql_query("SELECT id,ip FROM accounts ") or die (mysql_error());
while($fetch = mysql_fetch_array($query)) {

    // Get IP address (dotted)
    $ip_address = $fetch[ip];
    $id = $fetch[id];
   
    // Convert dotted ip address to IP number
    $ip_number = sprintf("%u", ip2long($ip_address));
   
    // Query database for country code
    $geo_query = mysql_query("SELECT COUNTRY_CODE2 FROM geoip WHERE IP_FROM <= '$ip_number' AND IP_TO >= '$ip_number' ") or die (mysql_error());
    $geo_fetch = mysql_fetch_array($geo_query);
    $geo_code = $geo_fetch[COUNTRY_CODE2];
   
    // Update account
    mysql_query("UPDATE accounts SET country='$geo_code' WHERE id='$id' LIMIT 1 ") or die (mysql_error());


}
Avatar billede elskermad.dk Nybegynder
26. april 2006 - 21:01 #1
man kunne sikkert lave noget join men skal du blot køre det én gang? eller skal det køres ofte?
Avatar billede kgp43 Nybegynder
26. april 2006 - 21:12 #2
kun én gang
Avatar billede coderdk Praktikant
26. april 2006 - 21:15 #3
UPDATE accounts a SET a.country = g.COUNTRY_CODE2 WHERE g.IP_FROM  <= '$ip_number' AND g.IP_TO >= '$ip_number'

Men brug dog WS IP2C i stedet: http://weirdsilence.net/software/ip2c - Der er "databasen" binær og er MEGET hurtigere ;)
Avatar billede coderdk Praktikant
26. april 2006 - 21:19 #4
Hmm glem lige min SQL, jeg tror den gør mere skade en gavn :P
Avatar billede coderdk Praktikant
26. april 2006 - 21:20 #5
Jeg tror du gør det på den rigtige måde - Har du sat index på IP_FROM og IP_TO ?
Avatar billede kgp43 Nybegynder
26. april 2006 - 22:08 #6
er det kun muligt at sætte index på én ?
Avatar billede coderdk Praktikant
26. april 2006 - 23:00 #7
Nej, du skal lave et delt index

CREATE INDEX fromto_id ON geoip (IP_FROM, IP_TO);

Faktisk burde det virke med et UNIQUE index:

CREATE UNIQUE INDEX fromto_id ON geoip (IP_FROM, IP_TO);
Avatar billede kgp43 Nybegynder
26. april 2006 - 23:39 #8
UPDATE accounts a SET a.country = g.COUNTRY_CODE2 WHERE g.IP_FROM  <= '$ip_number' AND g.IP_TO >= '$ip_number'

- Hvordan ved den at den skal bruge tabellen "geoip" til at finde country_code ?
Avatar billede kgp43 Nybegynder
26. april 2006 - 23:41 #9
vil dette virke?

UPDATE accounts SET accounts.country = geoip.COUNTRY_CODE2 WHERE geoip.IP_FROM  <= '$ip_number' AND geoip.IP_TO >= '$ip_number'
Avatar billede coderdk Praktikant
26. april 2006 - 23:48 #10
Jeg tvivler på at den vil virke :P Som du kan se skriver jeg at du skal glemme min SQL :) Jeg vil klart anbefale ip2c eller lave index'er på din tabel og se hvordan det går ;)
Avatar billede kgp43 Nybegynder
26. april 2006 - 23:55 #11
coderdk: din kode virker ikke.

Dette skulle virke:
mysql_query("UPDATE accounts SET accounts.country = geoip.country_code WHERE geoip.IP_FROM  <= accounts.ip AND geoip.IP_TO >= accounts.ip ");

Men det gør det ikke, da IP skal konverteres:
$ip_number = sprintf("%u", ip2long($ip_address));

Hvordan får jeg flettet "sprintf("%u", ip2long($ip_address))" på "accounts.ip" ?
Avatar billede kgp43 Nybegynder
26. april 2006 - 23:56 #12
Skal kun bruge den én gang og har brugt de sidste 4-5 timer på det, så kan ikke lide at smide det ud :(
Avatar billede kgp43 Nybegynder
27. april 2006 - 00:01 #13
Troede dette ville virke, men det gør det heller ikke.
Skulle dog give et indtryk hvor jeg vil hen :)

mysql_query('UPDATE accounts SET accounts.country = geoip.country_code WHERE geoip.IP_FROM <= sprintf("%u", ip2long(accounts.ip)) AND geoip.IP_TO >= sprintf("%u", ip2long(accounts.ip)) LIMIT 10');
Avatar billede kgp43 Nybegynder
27. april 2006 - 00:10 #14
Har lavet et index, men den opdaterer kun 3596 accounts (ud af 175,000) - inden errors, den stopper bare.
Nogle forslag?
Avatar billede kgp43 Nybegynder
09. november 2008 - 18:32 #15
lukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester