Diskuze: paginator - výběr nebo ukládání
V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 24 zpráv z 24.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.
Tezko rici.
A v obou pripadech bys tu hodnotu musel SELECT prikazem vycist.
3. A potom je moznost neresit pocet stranek. Zkusit zobrazit stranky od-do, co uzivatel zada, at uz je to v limitu, ci ne. Bude to rychlejsi, ale uzivatel se muze proklikat na prazdne misto. Coz je uzivatelsky neprivetive.
U meho mailu mne celkem stve, ze nemuzu zadat cislo stranky, kterou chci
zobrazit a musim se tam proklikat po jedne.
U jineho programu to kolega resil tak, ze zobrazil prvni, posledni a par stranek
kolem vybrane pozice. Mozna by to chtelo spis pridat moznost, odkaz, pro
podrobnejsi vyhledavani. A nechat jinak sipky vpred, vzad, zacatek, konec, cislo
stranky, z kolika stranek/ Pripadne to jinak, co nejvice, zjednodusit.
Tady treba bracha zvolil jiny typ strankovace. nejspis to zobrazuje vsechny
stranky. Coz pri tisicovce zaznamu muze byt na prd. https://www.rar.cz/…_threads.php?…
hm, moc jsem to od tebe nepochopil. Když vložím článek do určtié rubriky tak zároven updatnu i pocet + 1 v dané rubrice ke které ten článek patří (když smažu článek tak to z toho počtu zas odečtu.)
A když budu chtít dělat paginator z určité rubriky (výpis článků) tak tam budu mít počet článků tak že nemusím dělat SELECT COUNT(*), otázka je zda to má smysl za tu režii, když smažu článek já sám z databáze tak už se ten počet neupdatne.
Ahoj, osobně nedoporučuji se o to starat ručně - databáze si s COUNT() dotazem poradí v pohodě a tobě se za to minimální ušetření nevyplatí:
A to neřeším situace, kdy bys chtěl do budoucna nějak ty články upravit, že mimo smazané bys chtěl rozlišovat i třeba "schválené (viditelné veřejně)/neschválené" atd. - akorát by sis ty sám přidával více práce, zatímco u COUNT() dotazu bys maximálně přidal jedno WHERE.
Pokud vůbec má nějakou výhodu ukládat a hlídat si ty počty ručně,
pak možná kdyby šlo o získávání tohohle čísla na základě
výkonnostně náročné operace, což ale obyčejné SELECT COUNT() bez WHERE
není
Pokud bys to ale vážně chtěl dělat ručně, spíš bych doporučil udělat to přes databázové triggery, u těch minimálně budeš mít jistotu, že nebudeš mít špatná čísla počtů v databázi, když třeba některý článek přidáš/smažeš ručně přes nějaký DB nástroj (Adminer, PHPMyAdmin, ...).
Edit: Nejsem si tímhle výrokem vůbec jistý, mám jen pocit, že jsem ho
kdysi někde četl a to,
že si databáze sama nějak ty počty ukládá, že při každém volání
COUNT() nepočítá znovu všechny řádky po jednom, tedy teoreticky to dělá
databáze za tebe, jen ne tak viditelně. Ale znovu říkám, nejsem si tímhle
jistý a vůbec to nemusí být pravda.
což ale obyčejné SELECT COUNT() bez WHERE není
to where by tam bylo WHERE SECTION = (number) rubrika
Pokud bys to ale vážně chtěl dělat ručně, spíš bych doporučil udělat to přes databázové triggery, u těch minimálně budeš mít jistotu, že nebudeš mít špatná čísla počtů v databázi
Já je nemažu ale označuju jako že jsou smazané, tudíž při vybírání
zde budou dvě where... where section a is_delete
Jinak tohle já řeším přes transakce takže byto neměl být problém, ale
otázkou je zda jsem taky všechno udělal správně
Řešíš teď zbytečnost
ať dotaz COUNT() trvá 0,0010 sekund nebo dotaz bez COUNT 0,0011 sekund, tak to
cílový návštěvník na webu nepozná
Databáze jsou optimalizované na to, aby zvládaly i desítky milionů záznamů, 2000 článků je pro ně nic. Ve tvém případě rozhodně se vyplatí investovat méně práce - tzn. ty řádky vážně počítat přes count, a ne ručně vést vlastní "statistiku".
Jestli 0,001 je na localhostu, tak na hostingu to bude ještě násobně
rychlejší. Vážně se tohohle nemusíš bát
Jo, presne to jsem se mu snazil rici, co napsal Martin Konečný.
Ze kvuli pocitani clanku bude mset pridavat dalsi sql dotazy, INSERT a DELETE. SELECT toho cisla bude sice rychly, ale nestoji to za to.
Nebo pouzije SELECT COUNT, ktery bude mirne pomalejsi, ale v celkovem souctu sql dotazu z predchoziho bude mnohem vetsi zatez, takze toto je spravna volba.
A nebo nepocitat clanky ani pres insert/delete, ani pres select count. Dat tam proste nekonecny paginator. Coz ale zas neni pro uzivatele pohodlne. Ale usetris 1 sql dotaz. Takze, s ohledem na rychlost, je to nejrychlejsi reseni.
Samozrejme, kdyz si navrhnes spatne sql dotaz, tak i SELECT COUNT jde k certu. Takze, az to budes resit a bude to pomale, tak sem zkus dat sql dotaz. Pres php se to vypisuje treba jako
echo $query;
Ono na localhostu se to těžko nějak sleduje, protože na OS ti běží
dalších milion věcí, a to se někdy stane, že to zrovna tu databázi trochu
zbrzdí - na reálném serveru se to nestane, jelikož tam běží výhradně ta
webová aplikace. Řešit takovouhle optimalizaci bych začal, až když by to
začalo být podezřele pomalé, tzn. ne rozdíl 0,0001 vteřiny, ale rozdíl
třeba 50 milisekund (za jeden dotaz). Nicméně si myslím, že na malém webu
s 3000 záznamy v tabulce to bude rychlé, ať to uděláš jakkoliv to jedině bys musel udělat
tzv. N+1 problem (vytvářet DB dotazy v cyklech), abys měl třeba 2000 dotazů
na stránku, jinak mě nenapadá situace, kdy by to ve tvém případě mohlo
mít výkonnostní problém.
Jinak viz @Peter Mlich
protože na OS ti běží dalších milion věcí, a to se někdy stane, že to zrovna tu databázi trochu zbrzdí - na reálném serveru se to nestane, jelikož tam běží výhradně ta webová aplikace.
Já budu mít webhosting, ne VPS, ale přemýšlel jsem i o VPS, problém je že neumím nastavovat SSL a další věcičky + určitě webhostingy mají lecos zabezpečnené čemu já zase tak dobře nerozumím. Wedos nabízí i WMS kde se o to všechno postaraj ale je to drahý jak čert.
Já to myslel tak, že právě na tom hostingu jsou servery sloužící
primárně pro chod těch webových stránek - na rozdíl od operačního
systému na tvém PC, kde běží hodně dalších aplikací, které s tím
webem nemají nic společného (a tedy to brzdí). Tedy rychlost na localhostu a
na hostingu se nedá srovnávat
Mně se třeba projekt na localhostu načítá cca 700-900 ms, na hostingu je
to cca 80-120 ms podle mě
na malý článkový systém obyčejný webhosting bohatě stačí, a to jak
nabídkou služeb, tak i výkonem. Pokud by tvá aplikace byla pomalá, tak
určitě něčím jiným, než tím, že je tam COUNT(*) dotaz
hm, a kde máš hosting jestli můžu vědět?
Já mám aktuálně VPS u cesky-hosting.cz, sice to nemám ještě
spuštěné ostře, ale zatím mi to přijde v pohodě a klasický hosting by u nich
měl být taky v pohodě.
To mas spatne udelany projekt. Resp, hosting nejspis kesuje obrazky. Ale obecne, by na localhostu mel bezet projekt rychleji. To bys musel mit drahe servery jako seznam nebo google, abys mel takhle vyznamny rozdil proti localhostu.
Proč myslíš, že by na localhostu měl projekt běžet rychleji?
Řešíš teď zbytečnost ať dotaz COUNT() trvá 0,0010 sekund nebo dotaz bez COUNT 0,0011
sekund, tak to cílový návštěvník na webu nepozná
Mám forum kde vybírám složky a ukládám počet příspěvků a počet
témat + název posledního tématu.
Když budu mít 100 složek tak to nebude problém?
musel bych potom udělat o 200 více dotazů ve foreach cyklu.
Zkoušel jsem toto aby to bylo v jendom dotazu:
SELECT f.ID, f.nazev, f.popis, COUNT(a.folder) AS temata, COUNT(answ.co_ID) AS odpovedi
FROM fm_folder AS f
LEFT JOIN article AS a ON a.folder = f.ID
LEFT JOIN answer AS answ ON answ.a_ID = a.ID
WHERE f.category = 1 AND f.is_del = 0
group by f.ID
ale vracelo mi to divné výsledky. Nevíte kde je chyba?
No zásadní je nedostat se do tzv. N+1 problému, tj. to, že budeš mít cyklus a v něm pokládat DB dotazy. Obvykle horší výkonnostní problém, než nějaký složitý dotaz, je, že se hodněkrát komunikuje s databází - proto to bývá v cyklech problém. Výkonnostně vhodnější je udělat si dotaz jeden (nebo co nejméně), který ti vrátí všechna požadovaná data.
Ohledně dotazu asi nedokážu poradit, dokud neuvidím strukturu těch tabulek, které v dotazu jsou.
Když to napíšu zjednodušeně tak
--
-- Struktura tabulky `answer`
--
CREATE TABLE `answer` (
`ID` int(10) UNSIGNED NOT NULL,
`a_ID` int(10) UNSIGNED NOT NULL,
`obsah` text NOT NULL,
`autor` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Struktura tabulky `article`
--
CREATE TABLE `article` (
`ID` int(11) UNSIGNED NOT NULL,
`folder` int(10) UNSIGNED NOT NULL,
`nazev` varchar(150) NOT NULL,
`obsah` text NOT NULL,
`autor` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Struktura tabulky `fm_folder`
--
CREATE TABLE `fm_folder` (
`ID` int(11) UNSIGNED NOT NULL,
`nazev` varchar(50) NOT NULL,
`popis` varchar(150) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Klíče pro exportované tabulky
--
--
-- Klíče pro tabulku `answer`
--
ALTER TABLE `answer`
ADD PRIMARY KEY (`ID`),
ADD KEY `a_ID` (`a_ID`);
--
-- Klíče pro tabulku `article`
--
ALTER TABLE `article`
ADD PRIMARY KEY (`ID`),
ADD KEY `folder` (`folder`);
--
-- Klíče pro tabulku `fm_folder`
--
ALTER TABLE `fm_folder`
ADD PRIMARY KEY (`ID`);
--
-- AUTO_INCREMENT pro tabulky
--
--
-- AUTO_INCREMENT pro tabulku `answer`
--
ALTER TABLE `answer`
MODIFY `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT pro tabulku `article`
--
ALTER TABLE `article`
MODIFY `ID` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT pro tabulku `fm_folder`
--
ALTER TABLE `fm_folder`
MODIFY `ID` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
--
-- Omezení pro exportované tabulky
--
--
-- Omezení pro tabulku `answer`
--
ALTER TABLE `answer`
ADD CONSTRAINT `answer_ibfk_1` FOREIGN KEY (`a_ID`) REFERENCES `article` (`ID`);
--
-- Omezení pro tabulku `article`
--
ALTER TABLE `article`
ADD CONSTRAINT `article_ibfk_1` FOREIGN KEY (`folder`) REFERENCES `fm_folder` (`ID`);
COMMIT;
ve fm_folder jsou uložené složky
v article jsou témata
a answer jsou odpovedi na témata
No, a jaky ma byt vysledek, jak to mas v cyklu? Sql dotazy se preci v cyklu obvykle nepouzivaji. To ti dokaze pokryt grupovani, urcite, co chces. Pri importu se pouzivaji sql dotazy v cyklu, treba pro zakladani kategorii a tak.
Jo, jeste je tu moznost, vygenerovat si obsah predem a ulozit do html. Vis, pokud se jedna o seznam clanku, ktery se treba pul dne nezmeni, tak proc pokazde volat sql dotaz? at se pri editaci clanku prepise nejaky html soubor, ktery si pak do stranky includujes, include 'tmp/clanky.htm'; .
pokud jsou tyto dotazy velmi časté tak doporučuji ukládat počet článků nejlépe pres trigger, jinak select count(*) ... pokud to chces zrychlit tak pridat index
CREATE INDEX article_idx1 ON article (folder)
a SQL dotaz
SELECT f.ID, f.nazev, f.popis, COUNT( DISTINCT a.ID) AS temata, COUNT(DISTINCT answ.ID) AS odpovedi
FROM fm_folder AS f
LEFT JOIN article AS a ON a.folder = f.ID
LEFT JOIN answer AS answ ON answ.a_ID = a.ID
WHERE f.category = 1 AND f.is_del = 0
group by f.ID,f.nazev, f.popis
nebo pro vsechny kategorie viceradkovy vypis
SELECT f.ID,f.category, f.nazev, f.popis, COUNT( DISTINCT a.ID) AS temata, COUNT(DISTINCT answ.ID) AS odpovedi
FROM fm_folder AS f
LEFT JOIN article AS a ON a.folder = f.ID
LEFT JOIN answer AS answ ON answ.a_ID = a.ID
WHERE 1 AND f.is_del = 0
group by f.ID,f.nazev, f.popis,f.category
Zobrazeno 24 zpráv z 24.