Autor Zpráva
Pavel Calta
Profil
Dobrý den,
Rád bych se zeptal na optimální čas na vygenerování stranky.
Mam e-shop, na stránce detailu výrobku mám jen pár SQL dotazů, ale i tak to nějaky čas zabere. Je řekněme 0.18s na čele vygenerování stranky moc?

Je tam 7 dotazu do db, některé zaberou třeba 0.03s , to pak nascitane dá kolem těch 0,2.

V tabulkách jsou všude indexy, používám joiny tabulek atd.
Jsem nově na php7 a dříve jsem používal již dnes vymazané mysql_ dnes PDO, mám pocit, že PDO je pomalejší. Též jsem dříve nepoužíval tolik objektový přístup, ten mi též přijde pomalejší.
Tomášeek
Profil
Pavel Calta:
Bez znalosti konkrétních dotazů, e-shopu, apod. těžko říct.

Načtení stránky není jen položení SQL dotazů. A jestli je 0,18s OK? Může a nemusí být. Je 7 dotazů málo/moc? Těžko říct.
Pavel Calta
Profil
Tomášeek:
Rozumím.
Takže:
Stránka se nejdříve ptá databáze na to, jaké všechny modely a pohledy potřebuje. Ptá se i na základní texty, dle jazyku počítače.

Toto jsou všechno drobné na čas.

Přituhne při dotazech k produktu.
Produkt není jedna věc, ale má své barvy, navíc každá barva má své varianty. Ke každé variantě se počítá dostupnost u nás, dostupnost u dodavatele (dle tabulky, kam se periodicky tahají dostupnosti z XML dat), načítají se data obvykle doby dodání, zjišťuje se, zda ještě dneska můžeme zaslat, nebo je již expedice uzavřena, URL fotek atd...

Toto vše je v jednom dotazu.

Dále ale má výrobek mnoho alternativ a dalšího příslušenství, kde toto vše se počítá pro všechny tyto produkty.

25% zabere to hlavní, 75% zabere výpočet těch alternativ, příslušenství atd.

Na současné verzi webu je to například toto:
www.kocarky.cz/easywalker-qtro-plus

Nová verze (zde řeším rychlost jak to jde) není nikde veřejná, ale funkcemi obdobná.
I na této staré verzi zabere nejvíce právě to související zboží.

Nepoužívám cache, respektive nechci ji užívat na produktech, na výpisech ji mám nasazenou.
Keeehi
Profil
Na stránce co jsi uvedl mi stažení html trvá ~80ms. Z čehož 25ms je čekání na první byte. Což většinou odpovídá době generování stránky serverem + zpoždění sítě. Což je skvělý čas. Ovšem ty píšeš o časech o řád větší. Takže buď jsi neuvedl stránku na které je problém, nebo jsi se spletl a stránka se ti generuje do 100ms což je naprosto v pohodě a nebo máš TTFB opravdu 200ms ale v tom případě to bude zřejmě způsobené zpožděním sítě, jelikož že to zvládne server vygenerovat o řád rychleji víme. Možná to ale také je jen způsobené zátěží kde teď večer jsem na eshopu nejspíše sám, ale pokud jsi to měřil přes den, tak tam mohli být další lidé.

Nepoužívám cache, respektive nechci ji užívat na produktech
Pracoval jsem ve firmě která vytvářela eshopy. No a zrovna produkty (hlavně jejich cenu) jsme kešovat museli jelikož kombinací těch variant, barev, velikostí a dalších parametrů je hromada a některé z nich mohou ovlivňovat cenu. Navíc když se do toho přidají akční ceny, slevy na kategorie, vouchery a další tak už se jedná o opravdu komplexní výpočet a počítat to ve výpisu produktů za běhu pro každý produkt zvlášť už nebylo reálné. Pokud kešování zatím nepotřebuješ tak pro tebe jedině dobře, máš jednodušší život. S přidáním nějakých funkcionalit se ale stát může, že už výkon serveru stačit nebude. No a pak buď začneš kešovat nebo si koupíš výkonnější server.
Pavel Calta
Profil
Keeehi:
No.. Popravdě bych si nerad fandil. Dle mého jste se na tu stránku nejdříve podíval, pak ji teprve otevřel v tom měřáčku. Tedy zafungovalo cachování na straně serveru (opcache, mysql má vlastní cache).
Vycházím z měření microtimu. Napoprvé to ukáže třeba těch 0,17s, podruhé je to 0,05 a méně klidně.
Přidal jsem do URL parametr, kde pokud jdete přes něj, tak se na konci stránky pod patičkou ukáže ten čas. Níže je pár náhodných produktů.

www.kocarky.cz/easywalker-qtro-plus?UkazCas=1
www.kocarky.cz/tfk-joggster-adventure?UkazCas=1
www.kocarky.cz/hartan-racer-gt?UkazCas=1
www.kocarky.cz/mamas-papas-ocarro-kocarek?UkazCas=1

Ohledně toho kešování, dost se mu bráním, furt si říkám, že se to snad dá napsat tak, aby to nezabralo tolik času, ale jo, prostě těch dat je mnoho.
Třeba tento dotaz níže se snaží zjistit co nejvíce o každém produktu, ale jak píšete, velikosti, varianty atd...
Takže ten první kočárek má 3 varianty, každá 6 barev.
Ten kočárek má cca 30 volitelných příslušenství, většina z nich má také své barvy. Každá věc má nějaké dodací podmínky, skladem, neskladem, skladem u dodavatele, na cestě k nám, na cestě k dodavateli...

Dotazů do databáze se snažím mít co nejméně, co nejvíce jich poslat v jednom:
SELECT sklad_dodavatelu.Mnozstvi_Skladem as PocetSklademUdodavatele, bases.Objednaci_nazev, bases.Id_Pohoda,bases.Kod, bases.Dodani,bases.StavSkladem,bases.StavObjednano,bases.Stav_obj_dod, (bases.StavSkladem-bases.StavObjednano) as Count_Free, bases.Nazev, bases.Dodavatel, vyrobci_web.UsualDeliveryTime, bases.Predpoklad_Doruceni, bases.NaseNaskladneni,
bases.CenaInternet, bases.Akce, bases.Text, druhy_zbozi.Vip, pictures.Url, pictures.Popis, pictures.Barva, rel_zasoby.Kod_hlavicka, sklad_dodavatelu.Naskladneni, sklad_dodavatelu.IdDodavatele, hlavicky.Nazev as DruhVyrobku, (SELECT Datum FROM ppl order by Datum desc limit 1) as PosledniPPL, adb.MaxOdeslaniZbozi, adb.OcekavaneZboziSkladem
from bases 
LEFT JOIN sklad_dodavatelu on bases.Objednaci_nazev = sklad_dodavatelu.Id_Produktu
LEFT JOIN rel_zasoby on rel_zasoby.Kod_Pohoda = bases.Id_Pohoda
LEFT JOIN hlavicky on hlavicky.Id_Pohoda = rel_zasoby.Kod_hlavicka
LEFT JOIN vyrobci_web on vyrobci_web.Nazev = hlavicky.Vyrobce
LEFT JOIN hlavicky_druhy on hlavicky_druhy.Id_hlavicky = rel_zasoby.Kod_hlavicka
LEFT JOIN druhy_zbozi on druhy_zbozi.Id =  hlavicky_druhy.Id_druh
LEFT join pictures on pictures.Kod = bases.Kod
LEFT join adb on adb.adb_number_ids = bases.Dodavatel
where bases.Id_Pohoda in (".$Kody.") 
order by bases.Nazev, bases.Id_Pohoda



Teď se ta data samozřejmě ještě dále zpracovávají, tedy jsou tam cykly, které ke každému dopočítává, že pokud je to skladem, tak můžeme dneska vydat na prodejně, pokud ještě neodešla PPL, tak můžeme i poslat dneska (to je toto v dotazu SELECT Datum FROM ppl order by Datum desc limit 1), počítá se, zda to má dodavatel, kde dodavatel je (v ČR nám to od něj dojde za 1-2 dny, ze Slovenska 4 dny, jiné země zase jinak)
Kcko
Profil
Pavel Calta:
Mno, podívej se na GooglePage Speed Insight. Načítáš snad 30 JS a CSS souborů, to není moc košér. Spoj je do jednoho, zminifikuj, za-Gzipuj.
Tím bych asi začal.

Nastav korektní expiraci na obrázky a další soubory (htaccesss, ukázka je tady na d.jpw.cz).

Dále, není nikde psáno, že jeden SQL dotaz na A4 je lepší než 5 kratších samostatných.
Zkontroluj si indexy a podívej se na EXPLAIN.

Řešíš dotaz za 0,2s , ale na webu máš mnohem horší problémy.

Dále si data můžeš kešovat (kategorie / menu / produkty / produkt) , whatever.
Pavel Calta
Profil
Kcko:
Všemu rozumím a tato pohana je správná na stávající verzi webu.
Protože ale dělám právě novou verzi nyní, kde všechny "snadné" kroky mám udělané (právě gzipy, expirace, minifikace, jska do jednoho atd...).
Menu, kategorie, ty jsou již nyní kešované i na "staré verzi".

Nicméně,
je tedy lepší dotazy do DB více dělit? Měl jsem za to, že je právě naopak lepší (do nějaké míry) dotazy dělit?

Příkaz EXPLAIN užívám pro ladění dotazů. Díky němu jsem dosahl výrazného zlepšení.
Kcko
Profil
Pavel Calta:
Podívej, třeba na jednom nejmenovaném serveru DOWNLOAD serveru (českém), bylo zakázáno používat spojované dotazy. Prostě se položil dotaz a v cyklu se pokládaly další dotazy na navazující tabulky. Bylo tam šílené množství záznamů a JOINY to zabíjely.

Když se potřeboval změnit index nad nějakou tabulkou, tak nad tím programátorský tým seděl 2 hodiny a diskutoval o tom.

Já na svém webu také používám kombinaci obojího. Spojené dotazy nebo 1 dotaz a pak několik kratších dotazů, kdy si načtu data do polí a ty pak používám v asociaci s dotazy, které vrátí 1 "hlavní" dotaz.

Je to případ od případu a neexistuje univerzální řešení.

Je dobré mít co nejmenší počet dobře odladěných dotazů. Nikde není psáno, že můžeš mít na webu 30x dotazů a bude pomalejší než web s 5 dotazy.

Přijde mi, že to řešíš moc. Jestli jsi udělal nápravu frontendu jak říkáš, tak si můžeš ještě zapnout SQL slow log (nebo jak se to jmenuje), který Ti bude logovat pomalé dotazy. A pokud váháš nad nějakým dotazem, prohlédni si jeho EXPLAIN, podívej se, jestli používá indexy a případně řeš dál.

Nesnaž se za každou cenu u toho prosedět hodiny, abys něco zrychlil o 0,00x.
Pavel Calta
Profil
Kcko:
Děkuji za rady. Člověk se snaží udělat max pro to, aby to šlapalo co nejlépe.
Kcko
Profil
Pavel Calta:
Ano, já chápu, já to mám stejně (spanelskyfotbal.cz), tady sem se snažil taky o maximální optimalizaci. Je tam kombinace snad všeho (cache, dobře udělané dotazy, tam kde už to nejde, nebo to nevím nebo to prostě MySQL v 5.x verzi tak dobře neumí, jsem použil předpočítáná data do dalších tabulek, případně redundantní sloupce opět kvůli datům, které by se musely jinak počítat "live").
Také jsem se snažil zoptimalizovat frontend tak jak jsem Ti popsal již dříve.

Možná by Ti pomohlo, kdyby sis nainstaloval balíčky z Nette (Tracy a Database), abys viděl hned co se děje a monitoroval si snadno každou stránku viz files.rjwebdesign.cz/i2/20180823-120740.png), vidíš SQL dotazy, exekuční plán, čas generování stránky a další užitečné věci.
Keeehi
Profil
Pavel Calta:
Dle mého jste se na tu stránku nejdříve podíval, pak ji teprve otevřel v tom měřáčku.
Ano.

Tedy zafungovalo cachování na straně serveru (opcache, mysql má vlastní cache).
MySQL možná ano, tam s keší zkušenosti nemám ale opcache na to vliv nemá. Ta jen kešuje bytecode co vznikl z PHP scriptu a to na rychlost, vzhledem k náročnosti SQL dotazů, vliv nemá.
Pavel Calta
Profil
Keeehi:
Rozumím.
smitka
Profil
Pokud to chceš lovit milivteřiny, tak se hodí provést profilování kódu, tam uvidíš, jaká operace ti jak dlouho trvá. Ideální stav by měl být takový, že by většina stránek neměla dělat do DB vůbec žádný dotaz a načítat všechno z cache. Pokud probíhá nějaké náročnější filtrování, tak je dobré využít jiný typ databáze - třeba Elastic Search. Časté jsou především problémy na frontendu, ty kolikrát zabijí i jinak rychlý web, setkal jsem se třeba s načítáním desítky různých webfontů... Je potřeba vždy prioritizovat a řešit to od nejpalčivějších problémů.

Je mnoho moderních technologií, které výkonu mohou pomoci - HTTP/2, TLS1.3, Brotli, WebP.

Mám na toto téma starší článek: lynt.cz/blog/optimalizace-vykonu-webovych-aplikaci-na-co-se-zamerit

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0