[php/mysql] queries met serialize in een txt file gooien

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik kwam zojuist een mooie tutorial tegen op Zend over het wegschrijven van queries in een text file met de serialize functie, en ze weer binnehalen en inlezen met de unserialize functie.

Het idee is vrij simpel en logisch; als je een query opvraagt zet je deze array dmv de serialize functie weg in een .txt bestand.
Voordat je deze query opvraagt check je eerst of dit bestand bestaat, bestaat hij, dan haal je de query met de unserialize functie uit het bestand, bestaat hij niet, dan voer je de query uit en schrijf je hem weg.
Zodra de inhoud van de query verandert (bijv. bij het toevoegen van een reactie in een reacties tabel) delete je het query bestandje waardoor bij een volgende reacties view de nieuwe reactie uit de db wordt gehaald en de nieuwste query weer wordt weggeschreven in het bestandje.

Ik zit er nu over te denken hoe ik dit zou kunnen toe passen en of ik het zou toe passen.
Wat ik bijvoorbeeld zou kunnen doen, is het in m'n forum toepassen bij de boards en topics, en de querie bestandjes deleten als een posting wordt toegevoegd/gewijzigd.

Het zou op zich een stuk sneller gaan en efficienter zijn dan elke keer alles weer uit de database trekken.
Een nadeel is dat je wel erg veel querie bestandjes op je server krijgt te staan, en als je een forum hebt dat heel erg druk is dan heeft het niet eens veel zin aangezien de queries dan nog heel erg vaak worden binnengehaald/weggeschreven.

Het zou wel iets zijn voor een pagina met nieuwsberichten, waarbij het nieuwsbericht normaal niet zou worden aangepast.

Zijn er mensen van jullie die dit toepassen, zoja, hoe is je ervaring daarmee, zonee; lijkt het je wat?

Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

Verwijderd schreef op 28 January 2003 @ 14:18:
Het zou op zich een stuk sneller gaan en efficienter zijn dan elke keer alles weer uit de database trekken.
Een nadeel is dat je wel erg veel querie bestandjes op je server krijgt te staan, en als je een forum hebt dat heel erg druk is dan heeft het niet eens veel zin aangezien de queries dan nog heel erg vaak worden binnengehaald/weggeschreven.

Het zou wel iets zijn voor een pagina met nieuwsberichten, waarbij het nieuwsbericht normaal niet zou worden aangepast.

Zijn er mensen van jullie die dit toepassen, zoja, hoe is je ervaring daarmee, zonee; lijkt het je wat?
Het zou alleen sneller gaan voor de queries die niet vaak veranderen, die veel tijd kosten om uit te voeren en niet groot zijn.
Serializen en deserializen is qua tijd een enorm kostbare bezigheid. Bedenk dat een database enorm snel is, een query uitvoeren is vele malen sneller dan een query cachen, tenzij die query bijzonder complex is.
edit:
Deserializen en serializen loopt linear op met de grootte van de serialized form. Het zijn O(n) algo's


In mijn eigen CMS heb ik een enorm complexe query (5 joins op 3 tabellen) die zeer cache-baar is, hij geeft alleen andere resultaten als er een pagina verplaatst, verwijderd of toegevoegd wordt. Deze query cachen levert me veel winst op. Maar om bijvoorbeeld een zeer envoudige query: "SELECT * FROM forums" te cachen is vrij zinloos - het levert alleen verlies op, omdat serializen en deserializen zoveel tijd kost.

Bedenk tevens dat File i/o langzamer is dan DB i/o.

[ Voor 5% gewijzigd door kvdveer op 28-01-2003 14:27 ]

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hmm, dat wist ik nog niet.
Dan heeft het inderdaad vrij weinig zin om het op een forum toe te passen, echt veel complexe queries komen daar zowiezo al niet voor (bij mij tenminste niet, iig niet in de pagina's die veel opgevraagd worden :))

Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

Misschien is het een goed idee om het gewoon eens te meten? Met microtime() kun je kijken wat er echt het snelst is. (dan weet je het tenminste zeker)

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Ik denk dat serializen van data opzich wel een merkbaar stuk sneller is als queries uitvoeren, enige nadeel is dat wanneer je met meerdere webservers werkt je het ineens niet meer kan toepassen (of iig minder efficient).

Het hangt natuurlijk wel af van de systeem belasting en dergelijke.
Ow en kvdveer, waarom zou File i/o langzamer zijn dan DB i/o :?
Ik denk eerder dat dat andersom is (zolang je niet erin hoeft te zoeken, en je dirsysteem als een soort db-systeem gebruikt...)

Ow en dat managen van je cache is waarschijnlijk vrij lastig...

[ Voor 7% gewijzigd door ACM op 28-01-2003 14:53 ]


Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

ACM schreef op 28 January 2003 @ 14:53:
Ow en kvdveer, waarom zou File i/o langzamer zijn dan DB i/o :?
Ik denk eerder dat dat andersom is (zolang je niet erin hoeft te zoeken, en je dirsysteem als een soort db-systeem gebruikt...)
Je vergeet dat bestanden zijn geoptimaliseerd voor waarden > 1Kb. Bijna alle buffers die gebruikt worden om een bestand te lezen zijn > 1kb. Voor je database geldt dat niet.
Uiteraard is mijn stelling niet meer waar zodra je grotere waarden op gaat slaan in bestanden, maar zolang het onder de 1Kb blijft (zoals een integer bijvoorbeeld :P) dan is een DB efficienter.

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ACM schreef op 28 januari 2003 @ 14:53:
Ow en dat managen van je cache is waarschijnlijk vrij lastig...
Hoezo zou het lastig zijn dan?
kvdveer schreef op 28 januari 2003 @ 15:03:
[...]


Je vergeet dat bestanden zijn geoptimaliseerd voor waarden > 1Kb. Bijna alle buffers die gebruikt worden om een bestand te lezen zijn > 1kb. Voor je database geldt dat niet.
Uiteraard is mijn stelling niet meer waar zodra je grotere waarden op gaat slaan in bestanden, maar zolang het onder de 1Kb blijft (zoals een integer bijvoorbeeld :P) dan is een DB efficienter.
Als je een reeks postings op zou slaan dan kom je wel boven die 1KB, dus dat is weer niet zo'n probleem.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat je dan ook beter stukken HTML kan gaan cachen dan alleen queries.
Je bent nu ook je parsetime kwijt en kunt simpelweg met bijvoorbeeld Templates de stukken gecachde HTML in elkaar schuiven.
Ik doe dat ook en het scheelt een hele hoop load op de web- en database server.

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op 28 januari 2003 @ 15:18:
Ik denk dat je dan ook beter stukken HTML kan gaan cachen dan alleen queries.
Je bent nu ook je parsetime kwijt en kunt simpelweg met bijvoorbeeld Templates de stukken gecachde HTML in elkaar schuiven.
Ik doe dat ook en het scheelt een hele hoop load op de web- en database server.
Ben ik helemaal met je eens.
Doe ik zelf ook, en als je het goed doet scheelt dit veel load.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

kvdveer schreef op 28 januari 2003 @ 15:03:
Je vergeet dat bestanden zijn geoptimaliseerd voor waarden > 1Kb. Bijna alle buffers die gebruikt worden om een bestand te lezen zijn > 1kb. Voor je database geldt dat niet.
Je opslag is wat minder efficient ja, maar het ophalen van data uit je database is echt geen licht klusje hoor...
Uiteraard is mijn stelling niet meer waar zodra je grotere waarden op gaat slaan in bestanden, maar zolang het onder de 1Kb blijft (zoals een integer bijvoorbeeld :P) dan is een DB efficienter.

Ik zal straks wel weer es een benchmarkje ofzo draaien, als je geen zin hebt het zelf te doen ;)
Verwijderd schreef op 28 januari 2003 @ 15:13:
Hoezo zou het lastig zijn dan?
Omdat je niet een query-resultaat file mag verwijderen terwijl ie ingelezen wordt en dat soort "multi threaded" perikelen :)
Dat waar je database, doorgaans, al zorg voor draagt.

Acties:
  • 0 Henk 'm!

Verwijderd

ACM schreef op 28 januari 2003 @ 18:18:
Omdat je niet een query-resultaat file mag verwijderen terwijl ie ingelezen wordt en dat soort "multi threaded" perikelen :)
Dat waar je database, doorgaans, al zorg voor draagt.
Je hoeft hem toch ook niet te verwijderen, maar kan hem toch gewoon overschrijven?
Lijkt me stug dat de file niet gelockt wordt als hij gelezen wordt.. of is dit iets typisch Windows.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 28 januari 2003 @ 18:30:
Je hoeft hem toch ook niet te verwijderen, maar kan hem toch gewoon overschrijven?
Lijkt me stug dat de file niet gelockt wordt als hij gelezen wordt.. of is dit iets typisch Windows.

Overschrijven, verwijderen dat maakt mekaar niet zoveel :)

Het gaat erom dat er standaard geen readexclusive locks worden afgegeven bij mijn weten, dus je kan prima van een file lezen waar een ander nog in het schrijven is.
Je _kan_ wel locking eromheen bouwen hoor, daar is meestal ook wel support voor, maar je moet er wel weer rekening mee houden e.d. (wat als een thread voortijdig dood gaat die nog een lock had?)

Daarentegen kan je ook een of andere waarde aan het eind zetten die aangeeft dat de file compleet was, als die er niet was, dan las je niet de goede waarde en doe je je query.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
acm@x193056-3 temp $ more file_or_db.php
<?
    function getmicrotime()
    {
        list($usec, $sec) = explode(" ",microtime());
        return ((float)$usec + (float)$sec);
    }

        $value_to_retreive = 100;
        $retreived_value = 0;

        $fp  = fopen('tmpfile', 'w+');
        if($fp)
        {
                fwrite($fp, $value_to_retreive);
                fclose($fp);
        }

        $start = getmicrotime();
        for($i = 0; $i < 1000; $i++)
        {
                $fp = fopen('tmpfile', 'r');
                if($fp)
                {
                        fscanf($fp, '%s', $retreived_value);
                        if($retreived_value != $value_to_retreive)
                        {
                                echo "$retreived_value != $value_to_retreive ";
                        }
                        fclose($fp);
                }
                else
                {
                        echo "problem ";
                }
        }
        $end = getmicrotime();

        echo "1000 file fopens + reads took: " . ($end - $start)  . "\n";

        $conn = mysql_connect("localhost", $user, $pass);
        mysql_select_db("gottest");

        mysql_query("delete from test");
        mysql_query("insert into test values ($value_to_retreive)");
        mysql_close($conn);

        $start = getmicrotime();
        for($i = 0; $i < 1000; $i++)
        {
                $conn = mysql_connect("localhost", $user, $pass);
                mysql_select_db("gottest");
                $result = mysql_query("select bla from test");
                if($result && mysql_num_rows($result) > 0)
                {
                        $retreived_value = mysql_result($result, 0, 0);
                        if($retreived_value != $value_to_retreive)
                        {
                                echo "$retreived_value != $value_to_retreive ";
                        }
                }
                else
                {
                        echo "problem ";
                }
                mysql_close($conn);
        }
        $end = getmicrotime();

        echo "1000 mysql connections + reads took: " . ($end - $start)  . "\n";
?>
acm@x193056-3 temp $ php file_or_db.php
1000 file fopens + reads took: 0.0990099906921
1000 mysql connections + reads took: 0.785404086113

En volgens mij heeft php nog vals gespeeld met het niet echt sluiten van die 1000 connecties, maar ik heb niet zo'n zin de logs weer aan te zetten daarvoor :P
Pagina: 1