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.