/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Slet rækker i een tael, med indhold der ik~
Fra : Birger Sørensen


Dato : 01-02-09 12:46

Håber der er nogen der kan hjælpe med en effektiv løsning.

Jeg har et par tabeller, som jeg bruger til statistik over besøgende.

Den ene (stats) indeholder id, dato, ip og antal besøg.
Den anden (agent) ip og "agent" = browser.

Som det er nu, checkes hver gang en besøgende kommer, og der slettes
rækker fra stats, hvor datoen er mere end 84 dage gammel (statistikken
holder altså kun 12 uger - men det er fint nok til mit formål).

Det fungerer fint. Men...
For det første, er der ingen grund til at gennemføre check på datoen,
hver gang der er besøg. En gang i døgnet burde være tilstrækkeligt.
For det andet, vokser agent tabellen uden hæmninger.
For det tredie ville jeg gerne af med id attributen i stats.

Noget siger mig at cronjob er løsningen. Jeg har ikke prøvet den slags
før. Så hvordan gør man? (servage)
At agent tabellen vokser, kunne jeg løse ved at gennemgå tabellen og
fjerne de rækker hvis ip ikke er i stats. Hvordan ser en query ud, der
fjerner rækker fra agent, hvis IP ikke findes i stat?
Id i stat er bare et nummer. Autoincrement. Men det bruges aldrig. Jeg
kan ikke umiddelbart sætte nogen af de andre som index, da de ikke er
entydige. Så skal de kombineres - der findes kun den samme dato og IP
een gang. Kan man det? Hvordan? (Jeg ved nok for lidt om indexering...)

Håber nogen kan give nogle hints...

Birger

--
http://varmeretter.dk - billig, sund og hurtig mad
http://bbsorensen.dk



 
 
Stig Johansen (02-02-2009)
Kommentar
Fra : Stig Johansen


Dato : 02-02-09 16:45

Birger Sørensen wrote:

> Håber der er nogen der kan hjælpe med en effektiv løsning.
>
> Jeg har et par tabeller, som jeg bruger til statistik over besøgende.
>
> Den ene (stats) indeholder id, dato, ip og antal besøg.
> Den anden (agent) ip og "agent" = browser.
>
> Som det er nu, checkes hver gang en besøgende kommer, og der slettes
> rækker fra stats, hvor datoen er mere end 84 dage gammel (statistikken
> holder altså kun 12 uger - men det er fint nok til mit formål).
>
> Det fungerer fint. Men...
> For det første, er der ingen grund til at gennemføre check på datoen,
> hver gang der er besøg. En gang i døgnet burde være tilstrækkeligt.
> For det andet, vokser agent tabellen uden hæmninger.
> For det tredie ville jeg gerne af med id attributen i stats.
>
> Noget siger mig at cronjob er løsningen. Jeg har ikke prøvet den slags
> før. Så hvordan gør man? (servage)
> At agent tabellen vokser, kunne jeg løse ved at gennemgå tabellen og
> fjerne de rækker hvis ip ikke er i stats. Hvordan ser en query ud, der
> fjerner rækker fra agent, hvis IP ikke findes i stat?
> Id i stat er bare et nummer. Autoincrement. Men det bruges aldrig. Jeg
> kan ikke umiddelbart sætte nogen af de andre som index, da de ikke er
> entydige. Så skal de kombineres - der findes kun den samme dato og IP
> een gang. Kan man det? Hvordan? (Jeg ved nok for lidt om indexering...)

Hvis du ikke bruger id til noget, så fjern den.
Indexer behøver ikke at være unikke.

Nu skriver du ikke ret meget om hvilken database du bruger, men lad os gætte
på mySQL (som jeg ikke selv bruger) men normalt er en
CREATE INDEX osv.. et ikke unikt index, hvorimod en
CREATE UNIQUE INDEX osv.. til gengæld unik.

Cronjobs er noget man sætter op på serveren, og er i store træk bare nogle
entries i en slags bat fil.
Hvorvidt du har mulighed for at lave egne entries i crontab'en må du
undersøge hos din udbyder.

I MS SQLServer kan man lave en DELET a lá
DELETE Agent FROM Agent LEFT OUTER JOIN Stats ON Stats.IP = Agent.IP WHERE
Stats.IP IS NULL
Men det ved jeg ikke om mySQL understøtter.

Alternativt kan du måske lave en delete ud fra en subselect, men her er jeg
heller ikke klar over hvor 'kapabel' mySQL er.

Mht. statistik og performance, så har jeg, sammen med en anden, lavet et
koncept, hvor vi logger entries i flade filer.
Disse filer(navne) bliver lavet ud fra datoen, så hvert døgn har sin egen
fil.
Efterfølgende loades disse filer ind i en database på anfordring.
På den måde belaster man ikke systemet med for mange database operationer
pr. visning.

--
Med venlig hilsen
Stig Johansenq

Birger Sørensen (02-02-2009)
Kommentar
Fra : Birger Sørensen


Dato : 02-02-09 17:56

Stig Johansen kom med følgende:
> Birger Sørensen wrote:
>
>> Håber der er nogen der kan hjælpe med en effektiv løsning.
>>
>> Jeg har et par tabeller, som jeg bruger til statistik over besøgende.
>>
>> Den ene (stats) indeholder id, dato, ip og antal besøg.
>> Den anden (agent) ip og "agent" = browser.
>>
>> Som det er nu, checkes hver gang en besøgende kommer, og der slettes
>> rækker fra stats, hvor datoen er mere end 84 dage gammel (statistikken
>> holder altså kun 12 uger - men det er fint nok til mit formål).
>>
>> Det fungerer fint. Men...
>> For det første, er der ingen grund til at gennemføre check på datoen,
>> hver gang der er besøg. En gang i døgnet burde være tilstrækkeligt.
>> For det andet, vokser agent tabellen uden hæmninger.
>> For det tredie ville jeg gerne af med id attributen i stats.
>>
>> Noget siger mig at cronjob er løsningen. Jeg har ikke prøvet den slags
>> før. Så hvordan gør man? (servage)
>> At agent tabellen vokser, kunne jeg løse ved at gennemgå tabellen og
>> fjerne de rækker hvis ip ikke er i stats. Hvordan ser en query ud, der
>> fjerner rækker fra agent, hvis IP ikke findes i stat?
>> Id i stat er bare et nummer. Autoincrement. Men det bruges aldrig. Jeg
>> kan ikke umiddelbart sætte nogen af de andre som index, da de ikke er
>> entydige. Så skal de kombineres - der findes kun den samme dato og IP
>> een gang. Kan man det? Hvordan? (Jeg ved nok for lidt om indexering...)
>
> Hvis du ikke bruger id til noget, så fjern den.
> Indexer behøver ikke at være unikke.
>
> Nu skriver du ikke ret meget om hvilken database du bruger, men lad os gætte
> på mySQL (som jeg ikke selv bruger) men normalt er en
> CREATE INDEX osv.. et ikke unikt index, hvorimod en
> CREATE UNIQUE INDEX osv.. til gengæld unik.
>
> Cronjobs er noget man sætter op på serveren, og er i store træk bare nogle
> entries i en slags bat fil.
> Hvorvidt du har mulighed for at lave egne entries i crontab'en må du
> undersøge hos din udbyder.
>
> I MS SQLServer kan man lave en DELET a lá
> DELETE Agent FROM Agent LEFT OUTER JOIN Stats ON Stats.IP = Agent.IP WHERE
> Stats.IP IS NULL
> Men det ved jeg ikke om mySQL understøtter.
>
> Alternativt kan du måske lave en delete ud fra en subselect, men her er jeg
> heller ikke klar over hvor 'kapabel' mySQL er.
>
> Mht. statistik og performance, så har jeg, sammen med en anden, lavet et
> koncept, hvor vi logger entries i flade filer.
> Disse filer(navne) bliver lavet ud fra datoen, så hvert døgn har sin egen
> fil.
> Efterfølgende loades disse filer ind i en database på anfordring.
> På den måde belaster man ikke systemet med for mange database operationer
> pr. visning.

Tak for dit svar.
Jeg sad i går og pløjede manualer - og databasen er mySQL - om index,
og primary keys.
Og fattede ikke en brik. Ved ikke om det er de små grå bag de lange
grå, influenzaen, eller fordi dokumentation pr definition skal være så
indviklet som muligt...

Anyhow.
Arbejder i phpmysqladmin hedder det vist.
Jeg prøvede at slette min id attribut. No can do - den er unqe index,
og må derfor ikke fjernes.
prøvede så at sætte de to andre kolonner sammen, til et index, men vist
forkert. Fik besked om at det kunne jeg ikke, fordi der er et indeks i
forvejen.
Fjernede så indexmarkeringen på id - det kan man godt, men man kan ikke
slette den?
Så kan jeg ikke oprette de to felter som index, fordi de hver for sig
ikke er unike.
Godt gemt, fandt jeg så den rigtige vej, til at definere et nyt unike
index, bestående af begge attributes.
Herefter slettede jeg id kolonnen.
HURRA. Syntes nu det er en del mere kompliceret end det behøver at
være...

Hvad angår det resten, træder jeg lige vande.
Servage har mulighed for at oprette cronjobs. Jeg har ikke prøvet, men
det ligner faktisk at man blot angivet et script man vil have kørt og
sætter en kalender - umiddelbart med mulighed for både daglig og
månedlig kørsel.
Har en anden mulighed, som jeg ikke har "set" før. Siden har en admin
del. Man kunne køre sin cleanup rutine når der logges ind - af en eller
anden årsag tiltaler det mig mere end et egentligt cronjob. Så
bestemmer jeg jo selv hvornår det skal gøres.

DELETE FROM agent WHERE NOT EXISTS( SELECT * FROM stats WHERE
ip=agent.ip)

Ser ud til at være det jeg har brug for. Har ikke testet endnu, men
skal nok rapportere...

Birger

--
http://varmeretter.dk - billig, sund og hurtig mad
http://bbsorensen.dk



Birger Sørensen (03-02-2009)
Kommentar
Fra : Birger Sørensen


Dato : 03-02-09 02:49

Birger Sørensen kom med følgende:
> DELETE FROM agent WHERE NOT EXISTS( SELECT * FROM stats WHERE ip=agent.ip)
>
> Ser ud til at være det jeg har brug for. Har ikke testet endnu, men skal nok
> rapportere...
>
> Birger

Er nu flyttet til at blive kørt, når jeg logger ind.
Og querien virker helt efter hensigten!

Birger

--
http://varmeretter.dk - billig, sund og hurtig mad
http://bbsorensen.dk



Stig Johansen (03-02-2009)
Kommentar
Fra : Stig Johansen


Dato : 03-02-09 05:27

Birger Sørensen wrote:

> Er nu flyttet til at blive kørt, når jeg logger ind.
> Og querien virker helt efter hensigten!

Det lyder godt, fik du styr på index'erne ?

--
Med venlig hilsen
Stig Johansen

Birger Sørensen (03-02-2009)
Kommentar
Fra : Birger Sørensen


Dato : 03-02-09 10:31

Stig Johansen skrev:
> Birger Sørensen wrote:
>
>> Er nu flyttet til at blive kørt, når jeg logger ind.
>> Og querien virker helt efter hensigten!
>
> Det lyder godt, fik du styr på index'erne ?

Det lykkedes mig i hvert fald at få sat dem som jeg forestiller mig de
burde være
Fræsede en masse dokumentation, uden at blive ret meget klogere.

Et link til en fornuftig SQL teoretisk gennemgang?

Birger

--
http://varmeretter.dk - billig, sund og hurtig mad
http://bbsorensen.dk



Stig Johansen (04-02-2009)
Kommentar
Fra : Stig Johansen


Dato : 04-02-09 06:06

Birger Sørensen wrote:

> Stig Johansen skrev:
>> Birger Sørensen wrote:
>>
>>> Er nu flyttet til at blive kørt, når jeg logger ind.
>>> Og querien virker helt efter hensigten!
>>
>> Det lyder godt, fik du styr på index'erne ?
>
> Det lykkedes mig i hvert fald at få sat dem som jeg forestiller mig de
> burde være
> Fræsede en masse dokumentation, uden at blive ret meget klogere.
>
> Et link til en fornuftig SQL teoretisk gennemgang?

Det kan jeg nok ikke hjælpe dig med, men du kan mit billede ud fra
pascal/delphi.

Tabeller i databaser er kun flade filer, du man kan betragte din stats tabel
som
record
id : integer ;
dato : datetime ;
ip : string ;
antal : integer ;
end;

Når der ikke er indexer på, skal hele tabellen gennemløbes foir at finde
værdier.

Nogle databaser, eller måske de fleste har den der autoincrement tæller.
Det er mere eller mindre kun det interne recordnummer, og vil formentlig
opfattes som (primary) index i databaserne.

Andre indexer skaber en 'fysisk' fil i databasen med nøgleværdien samt et
recordnummer.
Disse index 'filer' er typisk b-tree filer, der har den egenskab, at de også
er sorterede.

Denne pre-sortering kan man udnytte hvis man har mange læsninger med
sortering, da 'sorten' bare er en 'lineær' læsning i indexfilen.

Hvis du f.eks. har et udtræk med ORDER BY IP,dato - vil et compound index på
ip+dato give en væsentlig performanceforbedring.

Men træerne vokser ikke ind i himlen, den performance man vinder ved
læsning, taber man ved skrivning.

For hver skrivning skal de forskellige index-'filer' også opdateres.

I dit tilfælde er det skrivning, der er kardinalpunktet, så
performancemæssigt ville det være bedst at undlade indexer, og skrive det
hele.

Men da det kan se ud som om du laver en update where IP=.., er det en god
ide at have index på IP.

Nu skriver du, at du bruger phpmyadmin, og det kan muligvis være den der gør
det 'besværligt'.

Normalt skriver man bare DROP INDEX hvis man vil fjerne et index, og CREATE
[UNIQUE] INDEX hvis man vil oprette.

Jeg bruger meget standard SQL, og almindelige datatyper, til disse ting i
stedet for 'hjælpeprogrammer'.

Det har den fordel, at det er (næsten) database uafhængigt.

Ja, selv Access er forbavsende hurtig og SQL compliant, hvis man behandler
den 'rigtigt'.

--
Med venlig hilsen
Stig Johansen

Birger Sørensen (04-02-2009)
Kommentar
Fra : Birger Sørensen


Dato : 04-02-09 12:21

Stig Johansen kom med denne ide:
> Birger Sørensen wrote:
>
>> Stig Johansen skrev:
>>> Birger Sørensen wrote:
>>>
>>>> Er nu flyttet til at blive kørt, når jeg logger ind.
>>>> Og querien virker helt efter hensigten!
>>>
>>> Det lyder godt, fik du styr på index'erne ?
>>
>> Det lykkedes mig i hvert fald at få sat dem som jeg forestiller mig de
>> burde være
>> Fræsede en masse dokumentation, uden at blive ret meget klogere.
>>
>> Et link til en fornuftig SQL teoretisk gennemgang?
>
> Det kan jeg nok ikke hjælpe dig med, men du kan mit billede ud fra
> pascal/delphi.
>
> Tabeller i databaser er kun flade filer, du man kan betragte din stats tabel
> som
> record
> id : integer ;
> dato : datetime ;
> ip : string ;
> antal : integer ;
> end;
>
> Når der ikke er indexer på, skal hele tabellen gennemløbes foir at finde
> værdier.
>
> Nogle databaser, eller måske de fleste har den der autoincrement tæller.
> Det er mere eller mindre kun det interne recordnummer, og vil formentlig
> opfattes som (primary) index i databaserne.
>
> Andre indexer skaber en 'fysisk' fil i databasen med nøgleværdien samt et
> recordnummer.
> Disse index 'filer' er typisk b-tree filer, der har den egenskab, at de også
> er sorterede.
>
> Denne pre-sortering kan man udnytte hvis man har mange læsninger med
> sortering, da 'sorten' bare er en 'lineær' læsning i indexfilen.
>
> Hvis du f.eks. har et udtræk med ORDER BY IP,dato - vil et compound index på
> ip+dato give en væsentlig performanceforbedring.
>
> Men træerne vokser ikke ind i himlen, den performance man vinder ved
> læsning, taber man ved skrivning.
>
> For hver skrivning skal de forskellige index-'filer' også opdateres.
>
> I dit tilfælde er det skrivning, der er kardinalpunktet, så
> performancemæssigt ville det være bedst at undlade indexer, og skrive det
> hele.
>
> Men da det kan se ud som om du laver en update where IP=.., er det en god
> ide at have index på IP.
>
> Nu skriver du, at du bruger phpmyadmin, og det kan muligvis være den der gør
> det 'besværligt'.
>
> Normalt skriver man bare DROP INDEX hvis man vil fjerne et index, og CREATE
> [UNIQUE] INDEX hvis man vil oprette.
>
> Jeg bruger meget standard SQL, og almindelige datatyper, til disse ting i
> stedet for 'hjælpeprogrammer'.
>
> Det har den fordel, at det er (næsten) database uafhængigt.
>
> Ja, selv Access er forbavsende hurtig og SQL compliant, hvis man behandler
> den 'rigtigt'.

Tak for den forklaring. Det svarer nogenlunde til hvad jeg gættede mig
til ud af dokumentationen.

Det UPDATE jeg gør, er dog WHERE ip='..' AND dato='idag" fordi hverken
ip eller dato er unike, men kombinationen er.
Og det var derfor jeg ville have kombinationen som index.

Og ja - jeg har også en fornemmelse af, at det var phpmyadmin der kørte
en del rundt med mig... :-?

Praktisk, tror jeg ikke det har den helt store betydning - så skal vi
vist til at have en del flere besøgende - det var egentlig mest fordi,
det her eksempel er så simpelt, at jeg ville bruge det til at få lidt
bedre indsigt i begreberne...

Birger

--
http://varmeretter.dk - billig, sund og hurtig mad
http://bbsorensen.dk



Søg
Reklame
Statistik
Spørgsmål : 177577
Tips : 31968
Nyheder : 719565
Indlæg : 6409071
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste