Vlákno názorů k článku PHP pro experty: Vyhledávání (2) - praktická realizace od sinuhet - ad pomalost (a predpokladam i zravost pameti): - Pristup...

  • Článek je starý, nové názory již nelze přidávat.
  • 18. 1. 2005 18:24

    sinuhet (neregistrovaný)

    ad pomalost (a predpokladam i zravost pameti):
    - Pristup k databazi funguje tak, ze se do pameti nacte cely result set, ktery se pak predava dale jako pole. U dotazu vracejicich par radku vam to mozna nevadi, ovsem co se kuprikladu stane, kdyz se pokusime zaindexovat uz existujici databazi? Metoda 'search::add_results' nacte celou tabulku ... Soubor 'ez_sql.php' je vubec kapitola sama o sobe.
    - Kdyz se v nejakem clanku objevi stokrat slovo 'konicek', tak v tabulce 'search' bude sto zaznamu, u nichz se, az prijde od nejakeho uzivatele dotaz na 'konicka', secte celkove 'score', a to pak s prislusnym id dokumentu preklopite do tabulky 'search_tmp'. Proc? Ve skutecnosti by stacila pouze tabulka 'search_tmp' s daty, ktera nesmyslne generujete stale dokola. Tabulka 'search' (alespon pri algoritmu, ktery pouzivate) je zcela zbytecna.
    - To, jak cvicite se 'search_tmp', abyste obhospodaroval "nakesovana" slova, akorat dale zpomaluje vyhledavani. Vubec mam pocit, ze se na databazi snazite posilat co nejvice (pokud mozno co nejdelsich) dotazu.
    - Mel byste vyzkouset index na 'search.value' a 'search_tmp.string'. Nicmene vzhledem k neprilis podarenemu navrhu bych i uveril, ze to nepomuze, nebot v 'search_tmp' odmazavate starsi vysledky (takze bude mala) a v 'search' se zbytecne opakuji data (takze selektivita beztak nebude ohromujici).

    ad race-conditions:
    Vetsinou se to toci kolem tabulky 'search_tmp', ktera funguje jako jakasi kes. Nikdo se ale uz neobtezoval zajistit jak konzistenci se 'search', tak dusledne oddeleni uzivatelu.
    Napr: 'search::_check_tmp' neupdatuje sloupec time. Takze az se za vhodnych podminek sejdou dva uzivatele, muze jeden promazavat tabulku 'search_tmp' pod rukama toho druheho, ktery se asi nebude stacit divit, co ze to dostava za vysledky.

    ad tokenizator:
    - Ten co tam mate, se hodi pro indexovani nezaludneho plain textu. Co se stane, kdyz kupr. nebudou za interpunkci mezery? Co se stane, kdyz budete indexovat texty s html formatovanim typu <code>strlen</code>?
    - Pouzivate jeden pro indexovani dat, a jiny pro parsovani uzivatelskych dotazu. Z cehoz vyplyva, ze pri hledani vhodnych retezcu, ktere v dokumentech urcite jsou, nemusite najit vubec nic.

    A je toho daleko vice. Vazne by me zajimaly podrobnosti o tech komercnich pouzitich. Navrh projektu a ani jeho implementace na me rozhodne nepusobi "expertnim" dojmem. Na rootu IMHO nema co delat, ale to je problem spise redakce, ze.

  • 19. 1. 2005 8:04

    markon (neregistrovaný)

    1) Nacteni celeho resultsetu jako pole nevadi a vykon to nekazi, i kdyz na to dost programatoru narazi. Pokud vim, je tam LIMIT 10, a pak se jedna o nacteni 10ti zaznamu. V pripade, ze se pouziva LIMIT tento pristup neovlivnuje vykon.

    2) Tabulka Search_Tmp je urcena pro vyhledavani vice slov, jinak by tam nemusela byt, s tim souhlasim.

    3) Tokenizator se da upravit. To je projekt od projektu, myslim ze to dost lidi zvladne.

    4) U tabulky search_tmp oddeleni uzivatelu neni treba. Take jsem uvazoval jestli se nemuze stat, ze by to jeden uzivatel mazal druhemu. Otazka je, jestli situace kdy dojde k tomuto selhani je pravdepodobna - v tomto pripade by musel dotaz na nejaky vyraz dojit stejne tak do 10us. A osetrovat tohle dalsim kodem mi prijde relativne zbytecne. Navic nejde o 1 radek, tech moznosti kolizi je tam dost, ale nejedna se preci o bankovni aplikaci, kde by jeden pripad z milionu neco znamenal.

  • 19. 1. 2005 15:51

    jkt (neregistrovaný)

    > nejedna se preci o bankovni aplikaci

    jiste, proto nebudeme pouzivat lockovani... ach jo...

  • 19. 1. 2005 22:14

    sinuhet (neregistrovaný)

    1) Ve verzi, kterou jsem si ja stahl (1.0.0), zadny limit neni. Limit by vykon samozrejme ovlivnil, protoze byste na db posilal mraky zbytecnejch dotazu. Programatori na tahani db dat do pameti narazeji opravnene, protoze jde o naprosto zbytecne plytvani pameti a procesorovym casem.

    2) Spatne jste to pochopil, zbytecna je tabulka 'search'. A s vyhledavanim vice slov to nema nic spolecneho.

    3) No pokud si maji uzivatele napsat i tokenizator, tak o cem byly ty dva clanky? Ale mate pravdu, stejne do nej bude treba rejpat, schvalne si poslete dotaz typu 'jedna -- hodne mezer -- dva'.

    4) Ono je to mnohem variabilnejsi, to s tema dvema byl jen drobny prikladek. Data ze 'search_tmp' si muze promazavat uzivatel i sam sobe a nikoho dalsiho na to nepotrebuje. Nebo kdyz vymazete dokument z indexu, v 'search_tmp' az pul hodiny zustanou viset stara data (dokonce metoda 'article_query' pravdepodobne specialne kvuli tomu pouziva left join, abychom o NULL vysledky neprisli). Atd ...
    Ano stary dobry pristup k chybam - tohle se preci nemuze stat, a kdyz tak, jednou za tisic let. Tech 10us si cucate z prstu (maximalne o nich lze uvazovat jako o dolnim odhadu), zalezi to na rychlosti a vytizenosti stroje + na konkretni delce dotazu od uzivatele. Komicky na tom je, ze se jedna o umele vytvoreny problem, protoze tabulku 'search_tmp' staci vygenerovat jen jednou, a nic z ni mazat nemusite. Ale to uz se opakuji.

    A to jsem se minule zapomel alespon letmo zminit o zachytavani chyb, ktere v podstate neexistuje. Takze kdyz neco nevyjde, uzivatel tridy 'article_search' to nema sanci zjistit (i kdyz je pravda, ze tohle se z vetsi casti tyka uz 'db_mysql').

  • 22. 1. 2005 0:24

    Ondrej Jombik (neregistrovaný)

    Rad by som sa vyjadril k prvemu bodu. Nie som celkom "in", pretoze kod som nestudoval, ale ak som pochopil diskusiu, v zasade sa jedna o riesenie problemu o viacnasobnej pouzitelnosti vysledkov z jedneho dotazu (query).

    Riesenie je mozne viacerymi sposobmi, pricom medzi najhorsie sa rata ulozenie celeho vysledku (result) do pola. Pokial je nasim cielom vykon a jedna sa o pomerne obsiahly vysledok (result), je vhodne pouzit metodu pretacania vysledku (result rewind). Na toto dobre posluzi funkcia mysql_data_seek().

    Zataz tak ostane na databazovom serveri, ktory si uschovava smerniky na zaznamy konkretneho vysledku (result). Tie, ak potrebujeme napriklad vypisat, jednoducho tahame (mysql_fetch_row()) a popritom spracovavame (vypisujeme). Ak ich potrebujeme spracovat opatovne, tak pretocime vysledok (result) a spracovanie opakujeme. Vyhodou je, ze nemusime plytvat pamatou PHP a nemusime tiez posielat sietou dalsi dotaz (query). V tomto pripade tak nejde ani o sietovu prevadzku (poslanie query vela trafficu nenarobi), ale o opatovne zatazenie DB servera (aj ked moderne DB servery uz maju query cache...).

    Ked uz data spracovavat nepotrebujeme, result _uvolnime_ a dame tak DB serveru vydychnut.

    Je skutocne pozoruhodne, ze vela PHP programatorov tento postup nepouziva, pritom sa s nim daju dosiahnut podstatne zlepsenia vo vykone.