[php] efficiente query

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • pdehoop
  • Registratie: September 1999
  • Laatst online: 04-06-2024
Waarschijnlijk een open deur vraag, maar was toch wel benieuwd of er iets voor is.

Ik heb een tabel met records, waarin elke record een bepaalde datum heeft in unix formaat.

Nu laat ik met een while functie alle records afgaan en als de datum dan in een bepaalde maand is, wordt het record afgedrukt. Dit is nadat ik de gegevens aan een variabele heb gekoppeld.
Dus if januari then etc...

Nu moet hij dus hiervoor alle records afgaan. Niet echt efficient.
Ik dacht zelf al, maar een extra kolom aan met de maand, maar op zich moet hij dan alsnog alle records afgaan, hij hoeft ze dan alleen niet in een while functie te zetten, aangezien de selectie dan al in de sqlquery zit.

Is de tweede optie, dus al sorteren in de sqlquery sneller dan met if then statement?

Of maakt het helemaal niks uit?
M'n gevoel zegt dat het niks uitmaakt, maar toch even navragen.

Of misschien weet iemand een handigere manier om dit soort datumzaken te regelen.

Acties:
  • 0 Henk 'm!

  • Coen Rosdorff
  • Registratie: Januari 2000
  • Niet online
in sql is zeker sneller.
Alleen met een datum colom is ranzig.
Gewoon even de eerste unix-timestamp van de maand uitrekenen en de laatste.
En dan met datum > $begin AND datum < $eind Je kan hiervoor mktime() gebruiken.

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
als je alle datums in januari wil hebben kun je gewoon
SELECT * FROM table WHERE MONTH(datum) =1
doen
En da's een stuk sneller ja :)

Waarom trouwens in unix formaat en niet DATETIME?

en lees ook deze pagina eens door

btw,
k dacht zelf al, maar een extra kolom aan met de maand,
da's nergens voor nodig. je kunt een kolom rustig twee keer (of 20x) selecteren, op een andere manier en een andere alias. je hoeft dus geen extra kolom daarvoor aan te maken

[ Voor 32% gewijzigd door marty op 27-03-2004 03:43 ]


Acties:
  • 0 Henk 'm!

Verwijderd

marty schreef op 27 maart 2004 @ 03:42:
als je alle datums in januari wil hebben kun je gewoon
SELECT * FROM table WHERE MONTH(datum) =1
hm, en die month(datum)=1 wordt serverside uitgevoerd (dus geïndexeerd)?

[ Voor 4% gewijzigd door Verwijderd op 27-03-2004 03:51 ]


Acties:
  • 0 Henk 'm!

  • pdehoop
  • Registratie: September 1999
  • Laatst online: 04-06-2024
geen idee waarom in unixtijd, maar dat heb ik altijd gebruikt in php.
Als ik data invoer, worden deze omgezet met mktime en date vice versa.

Heb me niet verdiept in de mysql data dingen, maar ik weet hoe ik nu met mktime moet werken enzo.
Hier kan ik dus inderdaad ook makkelijk met vergelijken, groter dan en kleiner dan, omdat het gewoon om een getal gaat.


Maar in de sql dus als specificeren is sneller begrijp ik uit bovenstaande reactie.
Dan ga ik voor elke maand maar even een if/elseif dingetje maken met bijbehorende sql statement.

Bedankt voor de toch nog interessante raad! :-)

Klein vraagje tussendoor.

if en elseif werkt hetzelfde als al die case dingen.
Is er nog iets te zeggen voor één van de twee om die te gebruiken, of is het gewoon wat je fijner vindt en dus geen enkel verschil?


Edit:

Heb even snel die pagina bekeken en die functies zijn best handig :P
Is de keuze persoonlijk? unixtijd gebruiken of die mysql datetime?

Het belangrijkste is dat ik data kan vergelijken. Dus dat een record alleen wordt geselecteerd als hij in de toekomst ligt. Bij unixtijd kan dit met een simpele groter dan, is er bij datetime ook zoiets simpels?

[ Voor 19% gewijzigd door pdehoop op 27-03-2004 05:15 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Als je al zo ranzig wilt scripten om te branchen over 12 verschillende maanden, gebruik dan for crying out loud een case statement.

Als je slim bent ga je even wat docu's doorlezen en begrijp je waarom en hoe je DATETIME gebruikt. Unixtime is overigens makkelijk om te zetten naar DATETIME formaat:
code:
1
date("Y-m-d H:i:s", mktime());


Verder, als je de huidige datum wilt invoeren in een mysql Dbase kun je NOW() gebruiken, hoef je niet eens in PHP de tijd te knutselen.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Verwijderd schreef op 27 maart 2004 @ 03:49:
[...]

hm, en die month(datum)=1 wordt serverside uitgevoerd (dus geïndexeerd)?
Nee.. MySQL heeft geen functionele indices. MySQL mag hier alsnog alle records doorlopen omdat ie van te voren niet weet wat de uitkomst van de functie is... :P

Als je veel records hebt en je weet dat je later per maand iets wilt doen is het geen slecht idee om even een char(6) aan te maken met daarin de maand (200403 bijvoorbeeld). Dat maakt het werk voor MySQL een stuk eenvoudiger :)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Bosmonster schreef op 27 maart 2004 @ 10:51:
Nee.. MySQL heeft geen functionele indices. MySQL mag hier alsnog alle records doorlopen omdat ie van te voren niet weet wat de uitkomst van de functie is... :P

Als je veel records hebt en je weet dat je later per maand iets wilt doen is het geen slecht idee om even een char(6) aan te maken met daarin de maand (200403 bijvoorbeeld). Dat maakt het werk voor MySQL een stuk eenvoudiger :)
Als je dan toch weet dat het getallen zijn, maak er dan een (small/medium/gewone)int van, vergelijkingen tussen getallen zijn sneller uit te voeren dan vergelijkingen tussen teksten.
En een integer is 4 bytes, terwijl jouw char(6) 6 bytes nodig heeft :)

De snelste manier is waarschijnlijk zoiets:
- Maak een index op je unixtime-kolom
- En haal alles er uit met een select-query, waarbij je geen rekenwerk op die kolom uitvoert, zoals:
SELECT ... FROM tabel WHERE unixtime-kolom BETWEEN eersteseconde_van_de_maand AND laatste_seconde_van_de_maand

Als je bijvoorbeeld de huidige maand wilt hebben, kan je dat met zoiets doen:
voor de eerste seconde: UNIX_TIMESTAMP( FROM_DAYS( TO_DAYS(now()) - DAYOFMONTH(now()) + 1 ))
voor de laatste seconde: UNIX_TIMESTAMP( FROM_DAYS( TO_DAYS( ADDDATE(now(), INTERVAL 1 MONTH) - DAYOFMONTH(now()) + 1 ))

Die unix_timestamp-call is helaas nodig omdat je zo nodig een unixtime moest gebruiken en het is een groot nadeel dat SQL niet echt tussenresultaten van functies op laat slaan, waardoor je dit soort dingen allemaal (soms dubbel) in je queries moet opnemen en ze er dus wat luguber uitzien soms.

Acties:
  • 0 Henk 'm!

  • pdehoop
  • Registratie: September 1999
  • Laatst online: 04-06-2024
Ik zit niet vast aan de unixtijd, want alles draait nog proef, dus dat kan ik zo veranderen.

Als ik het goed heb begrepen moet ik dus de volgende query doen(het belangrijkste deel):

code:
1
WHERE TO_DAYS(NOW()) - TO_DAYS(datum) => 0 AND MONTH(datum)='$maand';

Hierdoor selecteerd hij de maand en liggen de records in de toekomst

En de kolom kan dan het beste een int(14) zijn? Op die manier kan ik ook nog de tijd bij een datum zetten.


Dit is dus de snelste en netste oplossing als ik het zo begrijp?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

pdehoop schreef op 27 maart 2004 @ 15:26:
En de kolom kan dan het beste een int(14) zijn? Op die manier kan ik ook nog de tijd bij een datum zetten.
Wat is er mis met het type datetime? Met een int werkt MONTH(veld) niet...

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • pdehoop
  • Registratie: September 1999
  • Laatst online: 04-06-2024
geen idee :-)

oke, datetime dus :-)
Pagina: 1