Vlákno názorů k článku PHP okénko: Získání počtu řádek od Vladimir Kralik - Clanok sa zaobera praktickou realizaciou problemu "Zistit pocet...

  • Článek je starý, nové názory již nelze přidávat.
  • 30. 3. 2005 9:32

    Vladimir Kralik
    Clanok sa zaobera praktickou realizaciou problemu "Zistit pocet riadkov vracanych selectom". Polozme vsak otazku : "Je to potrebne ?"

    Nemam namietky voci "select count(*)" ak je potrebne zistit iba pocet riadkov a nepotrebujem zistovat data. Je vsak velmi neefektivne ak po "select count(*)" nasleduje "select *" s rovnakou where podmienkou. Okrem v diskusii uz spominanom probleme s tranzakciami/zamykanim, je tu aj vykonovy problem ( priepustnost ).

    Na zistenie poctu riadkov musi databazovy server (je jedno aky DB server) vyhodnotit kompletnu mnozinu riadkov, to jest pristupit na vsetky riadky, ktore vyhovuju where podmienke ( pri vhodnom nastaveni indexov, pristupuje iba k indexom, nie k datovym strankam ). Ak nasleduje "select *" musi cely postup zopakovat este raz, ale teraz uz (zvycajne) musi pristupovat aj k datovym strankam. Navyse ak chcem mat zhodujuci sa vysledok zo "select count(*)" a "select *", tak musim obe operacie urobit v tranzakcii s REPEATABLE-READ.

    Samozrejme je tu moznost spocitat riadky na strane web/app-servera. To ale znamena nacitat vsetky vysledne riadky zo "select *" do pamati web/app-servera, takze pozor na potencionalne velke mnoziny riadkov. Sem samozrejme patri aj zataz/priepustnost siete medzi web/app-serverom a db-serverom.

    Skusme sa vsak zamysliet naco je potrebne zistit pocet zaznamov, ktore vracia select ? Zvycajne sa to zobrazuje na spodu stranky, aby uzivatel vedel ci ma este nejake dalsie nezobrazene riadky. Z praxe viem, ze pouzivatel zvycajne pracuje s najviac prvou, druhou, maximalne tretou obrazovkou, dalej sa mu zvycajne klikat nechce, je mu jednoduchsie obmedzit vracane riadky cez filter.

    Uzivatel vsak potrebuje vediet ci ma este dalsie riadky, alebo je uz na poslednej obrazovke. Na zobrazenie tejto informacie vsak nepotrebujem zistovat pocet riadkov zo selectu. Ak sa na obrazovku zobrazuje 100 riadkov, tak nacitam z DB 101 riadkov, ak 101 riadok existuje, zobrazi sa tlacitko "Next page".

    Na vybratie iba pociatocnej vzorky zaznamov je mozne pouzit vhodne obmedzenie DB servera ( napr Informix : "select first 101 *", PostgreSQL "select ... limit 101" ). Ak ma DB-server urobenu dobre optimalizaciu, nemusi vyhodnocovat celu mnozinu riadkov, staci ak vyhodnotil potrebny pocet riadkov.

    Pri tejto implementacii ma uzivatel dostatok informacii pre svoju pracu, na databazovy server ide iba jeden select a aj ten nemusi DB-server vyhodnocovat uplne do konca.

    Uff, je toho viac ako som myslel, takze iba zaver : Skor ako sa pustite do kodovania, urobte si navrh v ktorom zoberiete do uvahy spravanie databazoveho servera.
  • 30. 3. 2005 10:02

    Jakub Vrána
    "Je vsak velmi neefektivne ak po "select count(*)" nasleduje "select *" s rovnakou where podmienkou."

    Škoda, že jste si z článku důkladně přečetl jen první odstavec. Hned ve druhém odstavci je totiž uvedeno "Funkci mysql_num_rows je vhodné použít pouze v případě, kdy data z tabulky budeme tak jako tak potřebovat" i s názorným příkladem a způsobům vyhnutí se tomuto kódu je v podstatě věnován celý zbytek článku.

    Co se druhé poloviny vašeho příspěvku týče, je to dobrý postřeh a v článku by to mohlo být zmíněno. "Zvažte, zda celkový počet řádků vůbec potřebujete."
  • 30. 3. 2005 11:00

    Vladimir Kralik
    > Škoda, že jste si z článku důkladně přečetl jen první odstavec
    Preletel som to az do konca ( PHP ani mySQL nepouzivam ), takze viem ze to tam bolo uvedene, chcel som to iba zdoraznit.

    > v článku by to mohlo být zmíněno
    Moj prispevok smeroval k tomu, ze je velmi vela clankov, ktore sa snazia riesit dosledky nejakeho problemu, casto je vsak jednoduchsie odstranit pricinu.

    Uzivatelia/analytici odchovani na FoxPro/DBase su zvyknuti na velky komfort, ktory poskytuje toto prostredie ( pocet riadkov / rychle hladanie ), a ocakavaju rovnake spravanie aj pri SQL-serveri. Programator sa zvycajne bez slova podriadi, potom riesi dosledky .... a pocuva poznamky o tom ako je to pomale ...
  • 30. 3. 2005 11:20

    Jan Mensik (neregistrovaný)
    Zajimavy postreh. Opravdu nekdy staci jen zobrazovat "Next Page" a nenacitat celkovy pocet nalezenych radku, ale musim Vam oponovat - vetsinou je celkovy pocet dulezity udaj.

    Mate pravdu v tom ze navstevnici klikaji na prvnich par stranek. Ale celkovy pocet vysledku je pro ne zajimavy udaj. Rika jestli jak presne byl jejich dotaz cileny a dle toho casto svuj pozadavek upravi.
  • 30. 3. 2005 12:05

    Vladimir Kralik
    > Ale celkovy pocet vysledku je pro ne zajimavy udaj.
    Ano suhlasim, obcas je to zaujimavy udaj.
    Preco ho vsak zobrazovat na kazdej stranke ? Tento udaj sa zobrazi az ked si uzivatel vyziada dany udaj.

    > Rika jestli jak presne byl jejich dotaz cileny a dle toho casto svuj pozadavek upravi.
    Otazka je ci skutocne potrebuje zobrazit pocet zaznamov, alebo potrebuje informaciu "je toho vela". Podla mna je mozne realizovat to napr. takto

    * na obrazovke sa zobrazuje 20 riadkov
    * pri selecte nacitam 10 obrazoviek ( 20 * 10 + 1 riadok )
    * ak bude select obsahovat aj 201 riadok, potom zobrazim info "je toho vela"
    ( tu uz budem potrebovat pocitat riadky na web/app-serveri, to je ale pri uvedenych poctoch zanedbatelne )
  • 30. 3. 2005 12:13

    Jakub Vrána
    No, získávat 201 řádek kvůli dvaceti a ještě s tím, že přijdu o informaci o celkovém počtu záznamů, to se většinu asi nevyplatí.
  • 30. 3. 2005 12:28

    Vladimir Kralik
    > to se většinu asi nevyplatí.
    To si musite otestovat sam :-)
    Zalezi to od povahy aplikacie. Ak mam databazu na rovnakom stroji ako WEB-server a male tabulky, ktore aj s datami vojdu do cache db-servera, tak sa to skutocne neoplati.

    Ak vsak s databazou komunikujem cez siet, v tabulke mam 100 milionov zaznamov a k tomu komplikovanu where-klauzulu tak to zacne byt o niecom inom ....
    Ten "select count(*)" dokaze poriadne zabit db-server.
  • 30. 3. 2005 16:20

    bez přezdívky
    Moje trocha: v pripadech, kdy je celkovy pocet vysledku zajimavy, by ve skutecnosti navstevnikovi stacil odhad - neboli neni nutne provadet zamykani nebo transakce, lze prohlasit ze cislo, ktere uzivatel dostane, bude dost presne pro jeho potrebu i kdyz dojde zaroven k insertu.

    Konecne, stejne neni mozne transakci ani zamkem udrzet konzistenci v dobe, kdy si uzivatel prohlizi stranku (a aplikace na serveru vlastne nebezi).