Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: DATETIME vs aikakoodi

Sivun loppuun

RikuS [19.08.2011 14:40:53]

#

Onko nopeampi hakea tietokannasta vaikka puolen tunnin välein merkintöjä aikakoodin avulla vai käyttämällä DATETIMEa?

Haussa käydään yleensä koko päivä läpi ja tietokantamerkintöjä on paljon.

$aika = strtotime("2011-19-08");
$aikavali = 1800;

for ($i=$aika; $i<$aika+86400; $aika+=$aikavali) {
	$sql = $connection->prepare("SELECT * FROM taulu WHERE aika_alku <= ? AND aika_loppu >= ?");
		$sql->execute(array($i, $i+$aikavali-1));
		while ($row = $sql->fetch()) {
			// tee jotain hakutuloksilla
		}
}

Lebe80 [19.08.2011 14:44:51]

#

Sitten vastakysymys. Tarvitaanko merkittävää nopeuseroa jostain syystä tässä asiassa?

Itse ainakin tykkään datetimesta sen ihmissilmän luettavuuden kannalta.

Sun looppiasi taas en tajua, kun voisi vetää tulokset vain aikajärjestykseen ja käsitellä ne php:lla, jos haluat niitä tuloksia vain näyttää aikajärjestyksessä.

edit:
ja aikakoodi on siis timestampin arvo?

RikuS [19.08.2011 14:54:54]

#

Kiitos vastauksesta!

Tarkoitus on verrata hakutuloksista saatua tietoa muihin tietoihin, eikä näyttää hakutuloksia aikajärjestyksessä. Kyseessä on kalenterityyppinen homma joka etsii puolen tunnin välein tietoja mitä on tallennettu ja käsittelee niitä.

Mietin että onko nopeudessa eroa tehdä esim. koko viikon kaikkien päivien haku esimerkkini mukaan vai pitäisikö tiedot muuttaa DATETIMEksi?

Ja kyllä aikakoodi tarkoitti timestamppia.

Grez [19.08.2011 14:57:52]

#

Oletan, että "aikakoodilla" tarkoitat kokonaislukuna tallennettua unix timestampia, koska tuskin haluat kysyä onko DATETIME nopeampi kuin DATETIME.

Periaatteessa ei pitäisi olla mitään eroa nopeudessa, kun kerran annat suoraan alku ja loppuajan. Jos jossain tietokantamoottorissa oikeasti olisi merkittävä ero nopeudessa, niin harkitsisin melkein tietokantamoottorin vaihtamista, sillä pakkohan siellä olisi muitakin isoja WTFiä sitten olla ;D

RikuS [19.08.2011 15:12:08]

#

Kyllä vaan aikakoodilla tarkoitan unix timestamppia, kuten tuossa esimerkissänikin on.

Kiitos kovasti!

The Alchemist [19.08.2011 17:16:21]

#

Paljon enemmän sinä hukkaat aikaa tekemällä saman kyselyn sata kertaa, siinä ei ole mitään järkeä. Ota kaikki tulokset ylös samalla kyselyllä ja iteroi yhdessä silmukassa tietyn aikavälin yli, jonka jälkeen siirrät aikaväliä eteenpäin jne.

RikuS [19.08.2011 18:31:29]

#

tarkoitatko jotain tämäntyylistä vai ymmärsinkö pahasti väärin?

$paiva = strtotime("2011-19-08"); // unix timecode päivämäärästä
$aikavali = 1800; // haun intervalli

// hae päivän tiedot tietokannasta
$sql = $connection->prepare("SELECT * FROM taulu WHERE aika_alku <= ? AND aika_loppu >= ?");
$sql->execute(array($paiva+86399, $paiva));

// käy tietokannan tiedot läpi
while ($row = $sql->fetch()) {

	// käy päivä läpi aikavälin mukaan jokaisen tietokannasta löydetyn kohteen kohdalla
	for ($i = $paiva; $i<$paiva+86400; $i+=$aikavali) {
		// tee jotain hakutuloksilla
	}

}

The Alchemist [19.08.2011 18:42:32]

#

Tee juuri niin kuin koet parhaaksi; koodi on sinun. Ainoa selkeä asia on se, ettet missään nimessä tarvitse kymmeniä tietokantakyselyitä per sivulataus.

Antti Laaksonen [19.08.2011 18:48:14]

#

Kahden silmukan käyttäminen sisäkkäin ei vaikuta järkevältä. Voisitko vielä kertoa tarkemmin, mitä koodisi on tarkoitus tehdä, niin voimme antaa parempia neuvoja asiaan.

RikuS [19.08.2011 18:52:07]

#

Kiitos! Sillä täällä kyselenkin kun en tiedä onko nopeampaa hakea tiedot kannasta puolen tunnin välein vai hakea kaikki tiedot kerralla ja käydä niistä jokainen läpi puolen tunnin välein.

RikuS [19.08.2011 19:04:05]

#

Koodin on tarkoitus käydä tietokannassa olevat merkinnät läpi, jotta tiedetään mihin kellonaikaan on tilaa uudelle esim. tunnin merkinnälle. Merkinnät voi olla päällekäinkin mutta päällekäin olevilla on maksimimäärä.

Hommahan toimii täysin ensimmäisessä viestissä olevan pätkän avulla, etsin sille kuitenkin parempaa toteutustapaa jos sellainen on tähän tehtävään olemassa. Itse uskoisin näistä kirjoittamistani pätkistä tuon ensimmäisen olevan kuitenkin nopeampi.

Antti Laaksonen [19.08.2011 19:18:15]

#

Yksi tehokas ratkaisu on käydä kaikki varaukset läpi samalla kertaa ja merkitä taulukkoon, mitkä kaikki (esimerkiksi) tunnin aikavälit on varattu. Tämän jälkeen taulukosta voi tarkistaa, mitä aikavälejä ei ole varattu.

Esimerkiksi jos aikavälit 8–10 ja 14–15 on varattu, taulukon kohtiin 8, 9 ja 14 tulee merkintä. Nyt esimerkiksi kohdassa 12 ei ole merkintää, joten aikaväli 12–13 on vapaa.

Metabolix [19.08.2011 19:20:03]

#

Eipä ole kauan siitä, kun keskusteltiin varauskalenterin täytöstä. Tuolla esitin erittäin yksinkertaisen algoritmin ongelmaan: Haetaan varaukset järjestyksessä alkuajan mukaan. Käydään läpi halutut jaksot aikajärjestyksessä. Joka jakson alussa lisätään aktiivisten varauksien joukkoon alkaneet ja poistetaan päättyneet. Saadaan siis helposti pidettyä kirjaa varauksista, jotka ovat voimassa kyseisellä aikavälillä, eikä tarvita kuin yksi tietokantahaku. Jos tätä jostain syystä pitäisi optimoida, voitaisiin pitää aktiiviset varaukset keossa loppuajan mukaan, mutta käytännössä tavallinen listakin riittää hyvin, jos päällekkäisiä ei ole satoja tai tuhansia.

Toinen hyvä tapa on tuo, jonka Antti yllä kuvailee. Paras algoritmi riippuu varauksien kokonaismäärästä, päällekkäisten varausten määrästä ja tutkittavan jakson pituudesta.

RikuS [19.08.2011 22:26:25]

#

Omassa sovelluksessa on mahdollisuus, että tallennetut varaukset eivät välttämättä ala tai lopu juuri samaan aikaan mihin jakson aikaväliä läpikäydessä muuten osuttaisiin. Olisiko seuraava toimiva ratkaisu? Onko parempaa tapaa selvittää osuuko hakutuloksen alku normaalille aikavälille?

$haku_alku = strtotime("2011-08-20"); // haku alkaa
$haku_loppu = $haku_alku + 86399; // haku loppuu
$aikavali = 1800; // haun aikaväli

$sql = $connection->prepare("SELECT * FROM testi WHERE alku <= ? AND loppu >= ? ORDER BY alku ASC");
$sql->execute(array($haku_loppu, $haku_alku));

// käydään hakutulokset läpi
while ($rivi = $sql->fetch()) {

		// jos löytynyt varaus ei ala samaan aikaan mihin haettava aikaväli osuu, merkitään varaus alkaneeksi edelliseen aikavälipisteeseen
		if (is_int(($rivi['alku']-$haku_alku)/$aikavali)) $nayt_alku = $rivi['alku'];
		else $nayt_alku = $haku_alku + floor(($rivi['alku']-$haku_alku)/$aikavali) * $aikavali;

		// jos löytynyt varaus ei lopu samaan aikaan mihin haettava aikaväli osuu, merkitään varaus loppuneeksi seuraavaan aikavälipisteeseen
		if (is_int(($rivi['loppu']-$haku_alku)/$aikavali)) $nayt_loppu = $rivi['loppu'];
		else $nayt_loppu = $haku_alku + ceil(($rivi['loppu']-$haku_alku)/$aikavali) * $aikavali;

		// lasketaan varausten määrät ja merkitään jos on varattu koko tila
		for ($i=$nayt_alku; $i<=$nayt_loppu; $i+=$aikavali) {
			if (isset($varaukset[$i]['maara'])) $varaukset[$i]['maara']++;
			else $varaukset[$i]['maara'] = 1;
			if ($rivi['koko_tila_varattu']) $varaukset[$i]['koko_tila_varattu'] = 1;
		}

}

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta