Avatar billede shjorth Nybegynder
19. juni 2009 - 13:02 Der er 24 kommentarer og
2 løsninger

sql streng der driller

Hejsa.

Nu har jeg simpelthen stirret mig blind på det her, håber der er nogen der kan se fejlen. Scriptet virker uden denne streng, så det må være her fejlen ligger :P

$q = mysql_query("SELECT * FROM am_users WHERE userid !='".$user_id."' AND userid NOT IN (SELECT friend FROM am_friends WHERE userid = '".$user_id."')")or die(mysql_error());
Avatar billede mrgumble Nybegynder
19. juni 2009 - 13:13 #1
Det ligner parenteserne, men det er det vist ikke.
Det jeg plejer at gøre er, at adskille sql-sætningen og query-kaldet, så kan jeg outputte sql-sætningen.

Desuden bruger du gåseøjne, men hopper ud for at indsætte en variabel.
Prøv det her, og se hvad der sker.

$sql = "SELECT * FROM am_users WHERE userid !='$user_id' AND userid NOT IN (SELECT friend FROM am_friends WHERE userid = '$user_id')";
$q = mysql_query($sql) or die(mysql_error());
echo $sql;
Avatar billede shjorth Nybegynder
19. juni 2009 - 13:39 #2
Hejsa, nu har jeg fået det til at virke, men jeg har 1 stort problem. Af en eller anden grund arbejder lige netop den query der utrolig langsomt. Der går ca 20 sek før siden er loaded ind, for den ene query.

Er der noget i det jeg kan/skal gøre anderledes? Eller kender du til hvor problemet kan ligge?

Mange tak
Avatar billede mrgumble Nybegynder
19. juni 2009 - 13:43 #3
Hvor store er de to tabeller du slår op i?
Avatar billede shjorth Nybegynder
19. juni 2009 - 13:46 #4
am_friends har ca 8.000 poster og am_users har ca 2400
Avatar billede martinbk Nybegynder
19. juni 2009 - 13:53 #5
har du nogle indexes på userid felterne i de 2 tabeller ?
Avatar billede shjorth Nybegynder
19. juni 2009 - 13:56 #6
Userid ser således ud:
`userid` bigint(20) NOT NULL,

Er der noget smartere jeg kan gøre?
Avatar billede shjorth Nybegynder
19. juni 2009 - 14:07 #7
`id` int(11) NOT NULL auto_increment,
  `userid` bigint(20) NOT NULL,

Jeg har altså også en id på
Avatar billede martinbk Nybegynder
19. juni 2009 - 14:09 #8
er det hele definitionen ?

hvis så hvad formål har id feltet ?

et id felt er jo til for at man kan identificere en række på noget unikt, men hvis du aldrig bruger den ID er den overflødig
Avatar billede mrgumble Nybegynder
19. juni 2009 - 14:11 #9
Er det nødvendigt med et bigint som userid?
Jeg tror dine tabeller er for store, til at du kan bruge den sql-forespørgelse. Hvad skal den gøre? Returnerer alle de venner, som ikke er venner allerede?
Avatar billede martinbk Nybegynder
19. juni 2009 - 14:12 #10
helt enig en bigint (en 64 bit integer) virker ret overkill til et userid
Avatar billede shjorth Nybegynder
19. juni 2009 - 14:12 #11
Ja, bigint er nødvendigt desværre.. Men det der undrer mig er at jeg kan hive ting ud af en tabel med over 2 millioner poster uden problemer.. Det er kun i den her query at den er meget meget sløv :(
Avatar billede martinbk Nybegynder
19. juni 2009 - 14:18 #12
hmm en unsigned 32 bit integer kan indeholde værdierne fra 0 til og med 4294967296 vil da mene du kan holde en del brugere i den range, men igen kan du poste hele din tabel definition for de 2 tabeller ?

hhv.

SHOW FIELDS FROM Tabel

og

SHOW KEYS FROM Tabel

så har vi et grundlag for at hjælpe dig med performance optimering
Avatar billede shjorth Nybegynder
19. juni 2009 - 14:26 #13
am_users:

id      int(11)      NO      PRI      NULL      auto_increment
userid     bigint(20)     NO                
account     bigint(20)     NO                

am_users      0      PRIMARY      1      id      A      2737      NULL      NULL            BTREE     

am_friends:

id      int(11)      NO      PRI      NULL      auto_increment
userid     bigint(20)     NO                
user_comp     int(11)     NO                

am_friends      0      PRIMARY      1      id      A      8064      NULL      NULL            BTREE
Avatar billede mrgumble Nybegynder
19. juni 2009 - 14:28 #14
Du måtte nu også godt komme med en beskrivelse af tabellerne og felterne. Men hvorfor har du både en id og en userid? Hvad er forskellen?
Avatar billede shjorth Nybegynder
19. juni 2009 - 14:32 #15
hehe sorry.
Men altså am_users indeholder alle brugere. Grunden til jeg har id på dem er at jeg til dels har for vane at sætte id på alle mine tabeller, og så er det også en meget god måde at sortere på..?

At den er der, sløver det databasen?

am_friends indeholder så de brugere som er venner med personen her, og det er det det samme med id, en vane og fordi den er god at sortere efter ?

I øvrigt mange tak for hjælpen so far :)
Avatar billede martinbk Nybegynder
19. juni 2009 - 14:34 #16
som jeg troede du har kun et index på din primary key som er en helt normal integer, slår du nogensinde op på det id ? eller er det der bare for de blå øjnes skyld ?

anyways,

lav en backup af din database inden du begynder at ændre på strukturen.

derefter kan du forsøge med flg:

CREATE INDEX userid_index USING BTREE ON am_users (userid);

CREATE INDEX userid_index USING BTREE ON am_friends (userid);

og prøv så din query igen
Avatar billede mrgumble Nybegynder
19. juni 2009 - 14:37 #17
Nogle vaner er gode, det er din id desværre ikke i dette tilfælde. Og det eneste du får af at sortere på id'et er, den rækkefølge personerne/vennerne blev sat ind.

Har jeg forstået dit output korrekt; du har kun 3 felter i am_friends? I din sql-sætning spørger du efter "friend" men den står ikke i dit output??
Avatar billede shjorth Nybegynder
19. juni 2009 - 14:43 #18
Hov. Jo den er der jeg fik bare lige skåret den fra.

Nu har jeg lavet de index der og hastigheden blev markant forøget, nu er der ingen ventetid overhovedet.

Men een ting der undrede mig er at:
Nøglenavn:    Kardinalitet:
id            8070
userid_index  2017

Skal det være sådan? På am_users er tallet det samme
Avatar billede martinbk Nybegynder
19. juni 2009 - 14:50 #19
kardinalitet er antallet af unikke entries i indexet, dvs. der er 2017 unikke userid's i dine tabeller
Avatar billede shjorth Nybegynder
19. juni 2009 - 14:54 #20
Arh okay.. Så giver det mening :-) Herligt.

Lige et sidste spørgsmål. Når jeg laver insert i min db nu, skal jeg så gøre noget anderledes efter de her index er added?

Mange tusinde tak for hjælpen, og så må du/i gerne ligge et svar
Avatar billede mrgumble Nybegynder
19. juni 2009 - 14:56 #21
Næ, du indsætter bare som normalt. :)
Avatar billede martinbk Nybegynder
19. juni 2009 - 14:59 #22
nej du skal ikke gøre noget specielt når du tilføjer til tabellerne, indexet holder sig selv opdateret.


det eneste du skal være opmærksom på er at index forøger størrelsen på din database en del, det kan være et problem hvis du hoster dit site hos et relativt billigt webhost, de er ikke altid glade for store databaser


men jeg vil anbefale dig at læse lidt om databaser, så vil du opdage denne forunderlige verden.

f.eks. som mrgumble også gjorde opmærksom på, at smide id's omkring sig bare for at have dem er ikke speciel god praksis, tilføj de felter du har brug for og ikke mere

en kort artikel der forklarer hvad indexes er (meget overfladisk) http://aptoma.com/select.star/2008/06/26/mysql-indexes-to-mysql-what-green-kryptonite-is-to-smallville-universe-bizarro/

og linket du altid bør have i dine foretrukne (!!!)

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
Avatar billede shjorth Nybegynder
19. juni 2009 - 15:02 #23
Tusinde tak for hjælpen :) I har reddet min dag :)
Avatar billede mrgumble Nybegynder
19. juni 2009 - 15:03 #24
Fedt, så lærte jeg også noget. :o)
Avatar billede shjorth Nybegynder
19. juni 2009 - 17:21 #25
Lige et bonus spørgsmål :)

Kunne man med fordel putte index på alle de felter jeg bruger? Eneste ulempe er vel bare at min db kommer til at fylde mere??
Avatar billede shjorth Nybegynder
19. juni 2009 - 17:22 #26
Hov troede jeg havde accepteret.. Undskyld forsinkelsen :)
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