čtvrtek 9. února 2012

Jak se přichází o domov

Ne ten skutečný, ale virtuální. Konkrétně ten o kterém byl tento blog. Shadoworld už je nějakou dobu mrtvej. Vlastně shadoworld už byl nějakou dobu mrtvej i počas toho když byl jěště živej. Nejsem si jistý proč, ale populace klesala a klesala až nakonec na stránku chodili tak čtyři lidé asi dvakrát za týden.
Možná proto, že znovu obživlo Město mrtvých ve své původní podobě. Možná proto, že můj vývoj SW se spomalil, až prakticky zastavil. Možná... nevím.

Každopádně ta definitivní rána byla když mi vypršela doména, stránka vlastně pořád běžela (a možná jěště běží, nevím), akorát už neměla www adresu, museli by jste na ni jít přes IP. To je jedno, skrátka vypršela doména, a já neměl peníze na její obnovení, i když to bylo směšných 10 eur na rok, nebo tak nějak. A pak mi ji nějakej podnikavec vyfoukl, protože si všiml že měla jistou dobu celkem pěknou návštěvnost a hezky se umisťovala při určitých klíčových slovech v googlu.

Dost to bolelo, bylo to pro mě jako ztratit "domov". Kdo mě zná ten ví, že žiju celkem dost na internetu, na SW jsem chodil... relativně často, když jinde nebylo co dělat, tak jsem se tam prostě přihlásil, a ani jsem nepsal, jen jsem tam byl přihlášen, a byl to pro mě pocit podobný tomu jako když po práci přijdete domů a zvalíte se na gauč, a prostě tam jste...

A pak už nebylo kam. A vlastně ani nemělo smysl ho obnovovat, byl to už hodně opuštěný a mírně zchátralý domov...

Bylo to už dávno, snad před rokem? Nevím přesně, ale stejně, když tohle píšu, stále jsem z toho smutný.
Po celý čas když jsem na něm dělal, když jsme tam chodili, jsem myslel, že kdyby znovu obživlo MMko, byl bych rád. A pak se to stalo, a já rád nebyl.

SW byl můj miláček, na dlouhou dobu to bylo splnění mého snu o projektu který nikdy neskončí, nikdy nebude hotový, pořád se v něm budu vrtat a nimrat, a piplat si ho, stavět ho výš a výš...
A pak zemřel. Chvíli po tom co začal upadat můj zájem jelikož začal upadat zájem lidí co tam chodili.
Ne, nechci házet vinu na vás, není vaše, je moje, ale to je jedno, nechci házet vinu na nikoho, prostě se to stalo.

A je mi to líto.
Ale jak řekl Kiowa, možná bylo načase pohnout se někam dál. Ale kam? To zatím nevím. Snažím se teď dělat jiné věci, ale ve skutečnosti je až tak moc nedělám. Ale to už je můj problém.

Jen jsem chtěl říct... měl jsem ho rád. Měl jsem rád vás, lidi co jste tam chodili.
Každá řádka kódu, kterou jsem pro SW napsal, vznikla s láskou a radostí, pro vás, stejně jako pro mě. Každá minuta kterou jsem mu věnoval stála za to, kvůli vám, stejně jako kvůli mě, stejně jako kvůli tomu co jsem se počas tvorby SW naučil. A naučil jsem se toho hodně. Prakticky jen díky shadoworldu jsem se naučil programovat weby. A taky díky vám, prostřednictvím shadoworldu, jsem se naučil hodně věcí o životě, a přístupu k němu. Asi je nepoužívám, ale to už je můj věčný problém, nezchopnost použít své znalosti v praxi.

Stejně vám děkuju, za všechen ten čas, za všechny ty myšlenky co jsme si tam vyměnili, za všechny ty hádky, a "hádky", za všechnu srandu i nesrandu která se tam odehrála, za všechny rady, slova výčitek i podpory, které tam padly.

A... trochu mě mrzí že tohle je zároveň jakoby "sbohem", jelikož to vypadá že mnoho lidí co na SW (v době jeho největší "slávy") chodilo už nechodí na MM. Chybíte mi, MM a pak SW byly jediné kontakty které jsem na vás měl. Ale zároveň bych asi měl být rád, že jste se dostali do bodu kdy podobnou stránku už nepotřebujete. Přeju vám všem hezký život, a děkuju že jste se mnou, a s ostatními, kousky z něj sdíleli, a že jste mi dovolili s vámi sdílet kousky toho mého.

Mějte se hezky, a jestli nejste Mrtví, tak se snažte nežít ve Stínu. Snažte se žít na slunci, je tam mnohem příjemněji, tepleji. Já se o to budu snažit taky.

Sit lux vobiscum.

středa 2. června 2010

Jak se optimalizuje SQL

Už na SW2 byl (a pořád jěště je) takový malý problém... Problém, který se asi ani nemá šanci projevit, ale v rovině teoretické přesto existuje...

Equilibrium.
Přesněji řečeno, zjišťování jestli už uživatel při zpovědi hlasoval nebo ne.
Tento údaj totiž musí být zaznamenán pro každého uživatele, což znamená že je na to potřeba samostatnou tabulku... Už nevím jak je to udělaný v SW2, myslím že tak, že při načtení Equilibria se do $_SESSION uloží záznamy o všech hlasováních uživatele...

A to je právě ten problém - pokud je jich kolem řekněme... stovky, tak je jěště všechno relativně v pořádku... Ale pokud by jich bylo... řekněme... tisíc, a na SW by bylo přihlásených v jednom momentě (a Equilibrium si čtoucích) 10 lidí, už je to 10000 záznamů, které si musí server držet v paměti... A tak dále, s každým zahlasovaným equi a každým připojeným uživatelem toto číslo roste, nemluvě o tom že tato informace se musí každému uživateli dopravit do počítače pokaždé když otevře seznam equi...

V SW3 jsem to chtěl udělat korektněji - narvat všechno do jedné query, pokud možno... aby vytáhla zpovědi a k nim přidružené informace o tom jestli momentálně přihlášený uživatel už ve zpovědi hlasoval, nebo ne.

Problém je, že tahle query byla monstrózní už než jsem se do ní začal pokoušet zakomponovat tenhle kousek... Musela vybrat zpovědi které byly přístupné dotyčnému uživateli (pokud nebyl přihlášen tak ty viditelné všem, pokud byl přihlášen tak ty viditelné všem plus ty jen pro přátele, ale od těch kdo ho mají v přátelích, plus všechny vlastní), a pak k nim jěště z další tabulky připojit informace o uživateli který zpověď přidal.
(Jak sami vidíte, v trochu jiném pořadí, ale to je detail...)

Vypadala takhle:
SELECT swEquilibrium.*, swUsers.Status, swFriends.Friend
FROM swEquilibrium
LEFT JOIN swUsers ON swEquilibrium.Owner = swUsers.Username
LEFT JOIN swFriends ON swEquilibrium.Owner = swFriends.Owner
WHERE (Friend = '{$_SESSION["Username"]}' AND VisibleTo = 2)
OR (VisibleTo <= " . Word2Privileges($_SESSION["Privileges"]) . ")
OR (swEquilibrium.Owner = '{$_SESSION["Username"]}')
GROUP BY swEquilibrium.ID
ORDER BY DateAdded DESC
LIMIT 15 OFFSET {$p};

({$_SESSION["Username"]} obsahuje vždy jméno momentálně přihlášeného uživatele, nebo prázdný řetězec, pokud uživatel není přihlášen, a {$p} je stránkovací proměnná, to je nepodstatný detail.)

Myslím že tohle byla druhá nejdelší query kterou jsem kdy vyplodil... První byla tuším na výběr deníkového záznamu na titulku, nebo equi na titulku, nejsem si jistý...
To co následovalo, se ale určitě s přehledem dostalo na první místo.

Pokus č.1.:
SELECT swEquilibrium.*, swUsers.Status, swFriends.Friend
FROM swEquilibrium
LEFT JOIN swUsers ON swEquilibrium.Owner = swUsers.Username
LEFT JOIN swFriends ON swEquilibrium.Owner = swFriends.Owner
LEFT JOIN swVotes ON swEquilibrium.ID = swVotes.ID
WHERE (Friend = '{$_SESSION["Username"]}' AND VisibleTo = 2)
OR (VisibleTo <= " . Word2Privileges($_SESSION["Privileges"]) . ")
OR (swEquilibrium.Owner = '{$_SESSION["Username"]}')
AND swVotes.Owner = '{$_SESSION["Username"]}'
GROUP BY swEquilibrium.ID
ORDER BY DateAdded DESC
LIMIT 15 OFFSET {$p};

...když jsem tohle slepil dohromady, a pustil to, a s překvapením se díval že to neháže žádný error, a pak se z toho překvapení vzpamatoval, tak jsem zjistil, že ta query jěště pořád běží...
A běžela něco kolem sedmi vteřin... Eh... Jak bych vám to... No, sedm vteřin je na SQL query SAKRA hodně, hlavně když pracujete s tak malými (v poměru k tomu na co je SQL stavěné) množstvími dat jako já...

No jo, šest a půl vteřiny, co to má sakra být? Zapoměl jsem do tabulky swVotes nahodit indexy? (Kontrola) ne, nezapoměl, primární tam není, ale ten tam ani být nemá, každý column má sice jiné kódování (databáze je utf8, sloupce této tabulky byly některé v latin2), ale to by měl být detail, a krom toho když jsem to opravil a spustil znovu, žádná velká změna...

A pak mi to došlo...
JOIN pracuje tak, že spojí všechny záznamy jedné tabulky se všemi záznamy druhé tabulky... A až pak probíhá WHERE, což je vlastně podmínka která nevyhovující odfiltruje...

Takže když máte tabulku A s 10ti záznamy, a tabulku B taky s deseti, a uděláte na nich JOIN, získáte tabulku kde bude každý záznam z A uveden desetkrát, pokaždé spojen s jiným z deseti záznamů z B... Což znamená že výsledkem bude tabulka o 100 záznamech, ze které se pak většina zahodí, protože nevyhovuje podmínce...

...a když děláte 3 joiny za sebou, udělá se třikrát to samé, takže spojením tabulek A, B a C, každé o 10ti záznamech získáte... tadá, tabulku o 1000(!) záznamech... Ze kterých se pak zase většina kvůli podmínce zahodí...

Je třeba si ale uvědomit, že každé spojení dvou řádků z tabulky, nebo kontrola řádku jestli vyhovuje podmínce, vás stojí něco času... Ono jsou to tisíciny vteřiny, někdy možná ani to ne, ale když dvě tisíciny vteřiny vynásobíte tisíci...

Zpátky ke query. Takže fungovala, ale fungovala tak, že udělala maximálně monstrózní tabulku všech možností, a pak ji celou prošla a zahazovala všechno co nevyhovovalo podmínce...

Což znamenalo:
168 (equilibrium) x 169 (users) x 212 (friends) x 6933 (votes) = 41 730 448 032

Ehm... to číslo jsem si musel pomalu pročítat odzadu aby mi došlo jak je obrovský...
Skoro 42. 42 MILIARD řádků...

Ze kterých se pak zahodí všechny kromě PATNÁCTI (což je délka jedné strany ve výpisu Equilibria)... Efektivita příkazu... 15 / 41 730 448 032 * 100 = 0,000000035945%, a myslím že to je tak neskutečně giganticky obrovsky titěrná hodnota, že mi asi můžete gratulovat... :-D. V praxi to znamená, že 99,999999964055% z těch víc jak šesti vteřin se vyplýtvá na spacování dat, které se stejně zahodí...

Tak jsem si řekl, že tohle tedy ne, musí být i jiná cesta... A po pár pokusech-omylech jsem se dopracoval k tomuto:

SELECT *
FROM (SELECT swEquilibrium.*, swUsers.Status, swFriends.Friend
FROM swEquilibrium
LEFT JOIN swUsers ON swEquilibrium.Owner = swUsers.Username
LEFT JOIN swFriends ON swEquilibrium.Owner = swFriends.Owner
WHERE (Friend = '{$_SESSION["Username"]}' AND VisibleTo = 2)
OR (VisibleTo <= " . Word2Privileges($_SESSION["Privileges"]) . ")
OR (swEquilibrium.Owner = '{$_SESSION["Username"]}')
GROUP BY swEquilibrium.ID
ORDER BY DateAdded DESC
LIMIT 15 OFFSET {$p}) AS tmpEqui
LEFT JOIN ((SELECT swVotes.Owner AS VoteOwner, swVotes.ID
FROM swVotes
WHERE swVotes.Owner = '{$_SESSION["Username"]}' AND Cathegory = 'Equilibrium') AS tmpVotes)
ON tmpEqui.ID = tmpVotes.ID;

Což znamená, že nejdřív udělám to, co jsem udělal původně, pak z toho udělám regulerní virtuální tabulku (nevím jestli se tomu tak říká, to je můj pracovní název, jde o to že jakmile query skončí, ta tabulka přestane existovat, ale do té doby se chová jako kdyby byla pevně zapsaná na disku, což není, protože je slepencem několika tabulek), kde se vyskytují jen ty záznamy které chci, a k ní pak připojím informace o hlasováních.
(Ale taky už jenom o těch hlasech, které mají souvislost s přihlášeným uživatelem a momentálně zpracovávanou zpovědí.)

Rozepsáno do bodů:
1. pospojuj všechny tabulky a informace které budeme potřebovat
168 (equilibrium) x 169 (users) x 212 (friends) = 6 019 104 řádků.

2. Projdi všechny řádky a vyřaď zpovědi které nemůže vidět
6 019 104 -> XY řádků, nemůžeme přesně vědět kolik, ale jedná se o všechny záznamy od začátku SW, bude jich obvykle kolem 80ti, a čím starší stránka bude, tím jich bude víc, ale pořád to bude kolem 0,000002%, nebo tak nějak, prostě mizivé množství, téměř zanedbatelné, pro naše účely počítejme s těmi 80.

3. Spoj s tabulkou hlasování
80 x 1 (votes na které je podmínka, takže ke každému equi vrátí jen jeden záznam, v takovém případě se tabulka "nemnoží", jen se záznamy správně seřadí) = 80

4. Vyber jen ty záznamy, které odpovídají druhé podmínce (tzn. hlasující = momentálně přihlášený, kategorie = Equilibrium, a ID zpovědi = ID ke kterému patři hlas.
80 -> 15;

Takže v tomto případě musí SQL zpracovat 6 019 104 + 80 (skládání v bodu 3) + 80 (filtrování v bodu 4) = 6019264 řádků...

Což je o 99,9999422% až 99,9999822% efektivnější, než ta první query...
A taky je to znát, proběhne přibližně za 8 setin vteřiny...

(Disclaimer: Ty čísla nejsou úplně přesná, zaprvý nevím jestli mám join a filtrování skutečně počítat jako dva průchody tabulkou, hlavně když probíhají hned po sobě, kde by je teoreticky MySQL mohlo bez obav okamžitě zahodit, pokud nevyhovují, a zadruhý jsou to jen moje odhady toho, jak MySQL uvnitř funguje... Ale ten rozdíl je naprosto jasný i kdybych měl hned ve výpočtech 50%tní chybu.)

Jo, a tenhle blog venujem Tomášovi Abaffymu, pretože sa ma pár mesiacov dozadu spýtal čo viem o optimalizovaní SQL/databázy, na čo ma napadli len správne zaindexované tabuľky a viac som si nevedel príliš predstaviť čo by chcel optimalizovať, tak som mu napísal "nie príliš veľa".

Tak teraz, neviem síce ako veľa toho o optimalizácií SQL viem z globálneho pohľadu, ale určite viac ako predtým... :-)

pondělí 24. května 2010

Mrtvá mrtvola mrtvě mrtví, umrtveně se mrtvolí :-D

No jo, Shadoworld je zase jednou down, teď už to bude asi druhým měsícem, pokud se nemýlím.
Sorry, nebyly prachy na hosting, nebyla motivace, nebyla nálada, a vlastně si to stejně nikdo nevšiml.

Zareagovali na to dva lidé, DVA!
Trvalo jim to asi dva týdny od momentu co šel off.

Díky, FireFly a blackie :-).

No, ale co dál?

Dejte mi měsíc a pohnu světem :-D.

Pořád dělám na SW3 a konečně se blíží dokončení, a příští měsíc bude dokončen a nahozen online a zas vám všem pošlu otravnej newsletter, ale aspoň vás donutím se tam jednou přihlásit, aby jste si mohli v nastaveních posílání podobných newsletterů vypnout.

A pak už poběžíme trvale, slibuju.
A LU taky, trochu to rozběhneme, přeci jenom v tom už není jen moje práce, ale taky kupa práce lidí co napsali články, a jen tak se na to vykašlat by zaprvý nebylo nanic a zadruhý by to bylo nefér...

24.6. tam bude.
Chystejte dort :-).

pátek 25. prosince 2009

Newsletter

Tak jo, podruhé v životě jsem před chvílí poslal něco jako newsletter, tohle konkrétně byl mail s informací o spuštění LU, všem registrovaným na shadoworldu, což je kolem 750 lidí (ano, v seznamu obyvatel na SW je jich jen kolem 250, to proto že zbytek z nějakého důvodu není aktivován), a vzápětí mi na hlavní LU mail přišlo kolem 450ti oznámení o nedoručení zprávy, vypadá to že většina z důvodu neexistence dotyčné mailové schránky...

...to se pak vlastně ani není co divit, že se jim nepovedla aktivace :-)

Tak uvidíme, kolik lidí z těch 250ti kterým to přišlo, se přijde podívat, a možná si po delší době vzpomenou i na SW.

středa 23. prosince 2009

LuxUmbrum - nový internetový časopis!

LuxUmbrum je online, neoficiálně od půlnoci ze včera na dnes, oficiálně odteď (což je cca 12:50).

Tento projekt mě napadl už asi před rokem, a od té doby jsem o něm dlouho vlažně snil a přemýšlel jak to udělat... vzniklo asi 6 různých designů, pak dlouho nic, a pak jsem se jednoho dne naštval a řekl si, že jdu na to... Takže jsem začal programovat a pak jsem si uvědomil že ty designy co mám jsou nanic, zavřel jsem NetBeans, otevřel Fireworks, a stvořil to, co vidíte :-).

No a o 4 dny už existoval základ stránky, měl jsem předběžně zamluveno asi 6 lidí na psaní článků (kteří se pak v praxi poděli někam... bůh ví kam... :-D), a v podstatě jsem jen čekal a mírně nakopával lidi ať píšou a články posílají...

No a včera jsem si řekl že i když mám článků jen šest, přičemž pět do hudby a od jednoho člověka, tak už dál čekat nebudu, protože jinak se asi ostatní nerozkývou k ničemu.

Takže jsem dodělal registraci, upravil pár posledních záležitostí, hodil to na web, napsal editorial, přidal články, a... šel spát... :-D

Dneska ráno jsem pak jěště napsal recenzi na Paranormal Activity, ať je něco i ve filmech, a udělal pár úprav...

A teď jen čekám... Na první koment k nějakému článku... Nebo na první reakci na SW.
...nebo na to, kdy se mi sakra konečně na LU aktivuje Google Analytics... :-D

A v průběhu toho čekání jěště vylaďuju detaily... je třeba změnit barvu odkazů, a dodělat stránku nastavení, about a kontakt, ale to má čas...

A řeknu vám, je to nádhernej pocit, spouštět vlastní stránku... Od spuštění shadoworldu jsem na něj už i zapoměl... :-)

Zatím to trošku zívá prázdnotou, ale to je proto, že redaktoři jsou líné vši, a začali něco dělat až teď, když jsem jim poposílal link... Najednou jsou celí překvapení že "vono už je to online?"...

Ano, je... tak pište...

Jo, a kdyby jste někdo chtěli být redaktorem, tak se ozvěte a něco s tím uděláme :-).

pondělí 24. srpna 2009

GRAFY!!! :-D

Tohle jsem objevil.

Jako kam se hrabe pChart... :-D. Jak jednoduchostí použití, tak zchopnostmi. Tohle umí a dokáže mnohem víc, a mnohem snáze se to používá.

Takže to použiju na SW :-P.

Jo, abych nezapoměl, na SW se zase jednou intenzivně pracuje, jelikož mám najednou až moc volného času. Tak moc, jak bych ani sám nechtěl...

A bezsenné noci, takže například dneska jsem celou noc nespal a programoval testy. A pak grafy. S nima jsem se hrál asi 3 hodiny, a to jěště v tom pChartu... A pak mě napadlo, že je dost ubohej, tak jsem zkusil najít jestli neexistuje nějakej opensource flashovej graf, a... OBJEVIL JSEM.

Odkaz už byl uveden nahoře.
Máte se na co těšit :-P.

čtvrtek 26. března 2009

Bordel v Indexu.php

...takhle to vypadá v kódu SW3 na začátku souboru index.php, kam si píšu poznámky co je třeba udělat, nápady co nového tam udělat, a nástiny jak to udělat...

/*
A koment na titulke robí v exploreri nejaké blbosti, skontroluj to pre istotu,
aj keď viem ž vo finálke asi na titulke žiadne komenty nebudú...
(ale prečo nie? čo tak nejaký najnovší/najlepšie hodnotený?)
*/

/*
Vidíš, spojazdníme hodnotenie komentov ;-)
*/

/*
A keď sme pri hodnoteniach, tak aj hodnotenie citátov, dorob to do DB k nim,
a za citát dáme rúčku s palcom hore, akože "Líbí se mi".
*/

/*
A potom rovno na profil zoznam obľúbených citátov!
Vymysli, sprav :-P
*/

/*
Oné, prehliadanie notifikácií funguje, takže už len z rôznych častí sprav ich
generovanie a potom jeden cron ktorý o polnoci vymaže všetky označené ako read.
*/

/*
Ešte stále nemáš vyriešené ako budeš enablovať/disablovať veci v toolbare
podľa toho čo na príspevku človek môže robiť!
(Asi butem musieť toolbar generovať funkciou z phpčka podľa privilégií a druhu
príspevku...)
*/

/* Z ľavého menu treba ešte spraviť:
- Denník (0%)
- Profil (0%)
- Nastavenia (0%)
*/

/* Z pravého menu treba ešte spraviť:
- Podmienky (0%)
- Občania (0%)
- Podporte SW (0%)
- Vychytávky (0%)
- Fórum (na štýl birdzovského skôr, ten výpis) (0%)

A dodať tam:
- Správa (Hlasovanie o prideľovaní titulov, banovaní userov a podobne...)
*/

/* V hornom menu nefunguje alebo chýba:
- Bibliotheka
- Testy (Daemon Intus) - Longin ti pár poslal na mail alebo do pošty na SW
- Hřbitov (Pax Mortem) - toto bude na dllllho dlho...
- To väzenie, ktoré ešte nemá meno (Inferno?)
*/

/* Ďalšie veci:
- Vyhľadávanie! Inteligentné a dobré!
- Autotagovanie spovedí! To bude chcieť trochu experimentov, že?
- Možno autotagovanie článkov?
- Inteligentné prideľovanie vĺn (viď nižšie)
*/

/* Inteligentné prideľovanie vĺn:
1. úroveň - za príspevky len tie, čo presahujú určitú dĺžku.
2. úroveň - za tie príspevky čo presahujú určitú dĺžku, alebo sa za nimi debata
rozprúdila (veľký počet dlhších príspevkov reagujúcich na autora) - netuším ako
by som spravil toto, ale bolo by to lepšie. Čím povedzme že v priebehu 12 hodín od pridania
by autor dostal vlnu za každý príspevok v reťazi ktorá začala reakciou naňho.
Analyzoval a prideľoval by to cronový skript, takže by mal aj dosť času... Len neviem ako.

Pri článkoch - za dobré hodnotenie samozrejme, + za rozpútanie diskusie (reťaziace sa dlhšie komenty)

Pri citátoch - za pridanie (1 vlna), keď pri ňom človek (okrem autora) klikne že je dobrý
(ajaxom, aby to nespravilo reload stránky).
*/