Autor Zpráva
slovakCZ
Profil
Dobrý den,

řeším optimalizaci skriptu, jelikož velmi zatěžuje server.
Jednou z mých otázek je, co je méně náročné na výkon servru:
1. připojit se k databázi, vytáhnout data, vypočítat nějaký matematický výraz a výsledek uložit do databáze
nebo:
2. otevřít soubor v dané složce, vytahnout data, vypočítat nějaký matematický výraz a výsledek uložit opět do souboru
??

Tento skript má denně více než 700 000 zobrazení a vytváří velkou zátěž (neříkám, že nevhodný mysql dotaz je jediný problém)

Děkuji za odpověď,

Tom
Alphard
Profil
Nešlo by
3. připojit se k databáze a provést sql dotaz, který to spočítá?
4. použít cache? vážně je nutné počítat to 700 000x za den?
slovakCZ
Profil
- použít dotaz, který to spočítá není možné.. pracuji např i s file_get_contents(), kde z jíné url získávám data, která jsou pokaždé jiná a tudíž ani cache nepřipadá v úvahu.. žádný výsledek výpočtu není stejný, takže ta cache je opravdu mimo hru
__construct
Profil
slovakCZ:
otevřít soubor v dané složce, vytáhnout data
Ono je dosť podstatné aký veľký ten súbor bude a akým spôsobom tie dáta budeš vyťahovať.
slovakCZ
Profil
predpokladam ze by tam byly soubory 2... jeden by obsahoval jen cislo (vzdy pri otevreni by se pricetla jednicka) a druhy soubor by obsahoval IP adresy (oddelene carkou napr) a ty by se pomoci cronu mazali vzdy po 24hodinach... takze soubor muze dosahnout velikosti 1mb
__construct
Profil
slovakCZ:
dosahnout velikosti 1mb
Tak to by som asi volil DB
slovakCZ
Profil
__construct:
ok, dekuji za odpoved... asi to bude nejlepsi reseni
Joker
Profil
slovakCZ:
V databázi by to mělo výhodu, že by to mohla být jediná tabulka, něco jako
pristupy: id (PK, auto_increment), ip, cas
xmark
Profil
slovakCZ:
pracuji např i s file_get_contents(), kde z jíné url získávám data,

Jen pro jistotu, že správně chápu: opravdu 8x za sekundu vytahuješ odněkud data pomocí file_get_contents()?
Teď se trochu ztrácím. Na začátku píšeš, že skript běhá a chceš ho optimalizovat, teď píšeš "predpokladam ze by tam byly soubory 2"

Nechtěl bys to popsat trochu konkrétněji? Mám pocit, že optimalizovat bude možné jaksi na úrovni návrhu aplikace.
Konkrétně to co píšeš v [#5] je úkol typicky pro databázi. Jeden update a jeden insert budou s jistotou rychlejší než otvírání dvou souborů, zvlášť když jeden z nich má 1MB.
slovakCZ
Profil
ok, abych uvedl na pravou miru chod "aplikace" (tak bych to snad ani nenazyval)... jedna se o skript cca na 80 radku, kter ma obstaravat toto:
kdyz navstevnik prijde na stranku (nebo ji nacte pomoci iframu/javasciprtu) tak se kazdemu 5. (desatemu, patnactemu, dvacatemu.. vzdy nasobky 5ti) navstevnikovi ma zobrazit jista reklama (banner)... kdyz ovsem tento 5. navstevnik tuto reklamu v poslednich X hodinach videl, tak se mu nezobrazi a zobrazi se nasledujicimu navstevnikovi (tedy sestemu, ale od tohoto sesteho opet zas patemu)..

nejdrive tedy zjistim kolikaty navstevnik to je (dotaz na db), dale zjistim zda ma ulozene cookies (dotaz na db, jelikoz nazev cookies je ulozen v db), kdyz cookies ma ulozene tak provedu insert do db (vlozim do db ze IP navstevnika nezobrazila reklamu a je to jiz X ty navstevnik)... kdyz cookies nema ulozene, tak se dotazu na db, zda jiz tato IP zobrazila reklamu v poslednich X hodinach.. kdyz tato IP nezobrazila reklamu v poslednich X hodinach, tak pomoci file_get_content() vytahnu z jiste stranky reklamni text/banner a vlozim jej do stranky

takto to funguje... dotazu na DB tam je moc a vetsina zbytecnych (jsem si toho vedom)... ale nyni nabira diskuze jiny smer.. prvni dotaz znel, zda je rychlejsi otevreni/cteni souboru nebo dotaz na db... nyni uz to vypada tak, ze mi budete navrhovat jaky dotaz na db je zbytecny... :)
Mastodont
Profil
nejdrive tedy zjistim kolikaty navstevnik to je (dotaz na db)
No a nemá ten hosting SQLite nebo cache APC či něco podobného? Tohle je fakt hodně náročné.
slovakCZ
Profil
Mastodont:
nejsem si jisty, mohu se poptat.. ale kdyby nekdo vedel zda toto ma angel-hosting v Maxi tarifu tak mozna budete rychlejsi nez ja :)
Joker
Profil
slovakCZ:
Zkusím se jen trochu zamyslet, neříkám, že z toho bude ideální řešení.

- Tabulka id, ip, cas, reklama. Všechno může být číselného typu, tak by to snad mělo být rychlé. Sloupec reklama by byl 1 nebo 0, 1 byla-li zobrazena reklama.
- Při každém zobrazení stránky by byl potřeba dotaz: SELECT MAX(id) as idmax, SUM(IF(ip=$ip, reklama, 0)) as zobrazeno FROM pocitadlo WHERE cas > $min_cas, kde $ip bude IP návštěvníka a $min_cas čas, odkdy se počítá zobrazení banneru. Je teda otázka, jak bude tenhle dotaz rychlý.
Pokud by byl moc pomalý, alternativa jsou dva dotazy: SELECT MAX(id) FROM pocitadlo a SELECT COUNT(id) WHERE ip=$ip AND reklama=1 AND cas>$min_cas edit: možná lepší SELECT id FROM pocitadlo WHERE ip=$ip AND reklama=1 AND cas>$min_cas LIMIT 1, aby se to nenamáhalo počítat všechny
- V zájmu rychlosti bych zneužil sloupec id jako počítadlo, čili (bude zobrazena reklama) = (idmax % 5 == 0)
- Sloupec zobrazeno udává, kolikrát daný uživatel od $min_cas dostal reklamu. Bude-li to větší než limit (resp. nula), reklama se nezobrazí a skončí se.
- Pouze pokud nebyla splněna předchozí odrážka se do tabulky vloží další záznam. Čili kdyby pátý byl ten co už reklamu viděl, vůbec by se nevložil a ten další bude zase pátý.

Takové ne úplně čisté, ale mělo by to fungovat. Co do rychlosti bude zásadní ta druhá odrážka, bohužel nevím jednodušší dotaz, který by získal nejvyšší ID ze všech a současně zda některý řádek v daném čase a s danou IP má v reklama jedničku.
slovakCZ
Profil
Joker:
To si vubec nemusel.. zamyslel jsem se nad tim v praci a nasel jsem nekolik reseni.. konzultoval jsem i s tisem na icq a dospeli jsme take k nejakemu reseni.. nejdrive asi vzykousim to Tve, at vidim jake to bude mit dopady na snizeni zateze a pripadne zkusim sahnout po necem jinem.. kazdopadne dekuji za tvuj cas a myslenky, nebylo to vubec nutne a i presto si poradil. Tady se to hemzi snad jen ochotnymi lidmi ze? :)

kazdopadne reseni je asi dobre a jednoduche jak facka, takze zabrat by to melo
__construct
Profil
slovakCZ:
Ja si len dovolím podotknúť, že na ukladanie IP adries do DB má MySQL funkcie pričom stĺpec IP bude UNSIGNED INT. Je to tak od dosť rýchlejšie ako použitie VARCHAR(15) (ako mnohí používajú)
slovakCZ
Profil
__construct:
dobre vedet, dekuji

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: