Sziasztok!
Adott egy raktár program aminek az egyik függvénye pdf fájlt állít elő. Az adatokat mysql táblákból veszi és így rakja össze. A probléma az, hogy amikor rákattint a user az adott azonosítóra, hogy létrejöjjön a pdf fájl, nagyon sokáig teker a böngésző addig amíg letölthetővé válik a fájlt. Az alábbi függvény részletre gyanakszom, mert amikor kikommentezem, akkor pillanatok alatt létrejön az állomány.
Készítettem indexeket is, de akkor se lett gyorsabb. A táblákhoz tartozó adatbázis motor innodb.
A kérdésem, hogy van valami ötletetek, hogy hogyan lehetne gyorsítani a két lekérdezést és/vagy a két ciklust? Esetleg lehetne egyszerűsíteni ezt a részt?
$sql = $db -> query("SELECT tabla1.aruaz,tabla1.maz,tabla1.me AS menny,tabla1.bruttokg AS btt,tabla1.mee,
CONCAT_WS('=>',tabla2.itemno,tabla2.itemname) AS arumegn
FROM tabla1
LEFT JOIN tabla2 ON tabla2.id=tabla1.aruneve
WHERE aruaz=szuloaz AND tmod='polc' AND betarszam='$pono'
ORDER BY aruaz");
while ($data = mysql_fetch_array($sql,MYSQL_ASSOC)) {
$pdf->Ln();
$keret = 0;
$maz = $data["maz"];
$bttkg = $data["menny"]*$data["btt"];
$pdf->Cell($w[0],6,$maz,$keret,0,'L');
$pdf->Cell($w[1],6,"",$keret,0,'L');
$pdf->Cell($w[2],6,$data["menny"],$keret,0,'R');
$pdf->Cell($w[3],6,$data["mee"],$keret,0,'L');
$pdf->Cell($w[4],6,$data["btt"],$keret,0,'R');
$aruaz = $data['aruaz'];
$alsql = $db -> query("SELECT tabla1.regihely,tabla1.mee,tabla1.raktarhely,tabla1.me AS menny,tabla1.bruttokg AS btt,
CONCAT_WS('=>',tabla2.itemno,tabla2.itemname) AS arumegn
FROM tabla1
LEFT JOIN tabla2 ON tabla2.id=tabla1.aruneve
WHERE aruaz!=szuloaz AND kikapcs=0 AND ((szuloaz='$aruaz' AND regihely=0) OR regihely='$aruaz')
ORDER BY aruaz");
while ($aldata = mysql_fetch_array($alsql,MYSQL_ASSOC)) {
$pdf->Ln();
$keret = 'B';
$maz = '';
$bttkg = $aldata["menny"]*$aldata["btt"];
$pdf->Cell($w[0],6,$maz,$keret,0,'L');
$arumegn = $aldata["arumegn"];
if ($aldata["regihely"]==$data["aruaz"]) $arumegn.="==>".$aldata["raktarhely"]."!!";
$pdf->Cell($w[1],6,$arumegn,$keret,0,'L');
$pdf->Cell($w[2],6,$aldata["menny"],$keret,0,'R');
$pdf->Cell($w[3],6,$aldata["mee"],$keret,0,'L');
$pdf->Cell($w[4],6,$bttkg,$keret,0,'R');
}
}
- 2005 megtekintés
Hozzászólások
Kezdjük ott hogy azt se tudod, hogy mi lassú. Nem ártana itt-ott mérned at időt aztán vagy logolni, vagy a pdf végére csapni, akármi.
Ha az adatbázis lassú, akkor a schema ismerete nélkül senki se fogja megmondani hogy hogyan tudod gyorsítani, plána ha ilyen WHERE aruaz!=szuloaz AND kikapcs=0 AND ((szuloaz='$aruaz' AND regihely=0) OR regihely='$aruaz') csodák vanak a query-ben. Egy explain-t tolj rá, az beszédes szokott lenni.
- A hozzászóláshoz be kell jelentkezni
Kérdezd még a gyártótól. Ugye van support szerződésed :)
- A hozzászóláshoz be kell jelentkezni
hát, ez eléggé 1.0 módon van megírva.
én biztosan kiszedném a while-on belüli while-on belüli sql-t (mert ez így ugye minden alkalommal végrehajtódik).
a belső sql-t kiraknám előre, az eredményét egy asszociatív tömbbe és onnan szedegetném elő az értékeket.
ekkor a két while egymás után lenne, nyilván.
--
Gábriel Ákos
http://ixenit.com
- A hozzászóláshoz be kell jelentkezni
Fő okok így részletek nélkül: (kellene a tábla szerkezete, az explain által adott válasz, a pdf lib ismerete)
- a második lekérdezés (a while-on belül fut) egyesével kéri le az eredményeket, ez biztos, hogy nem hatékony így, tippre ez viszi el a legtöbb időt, ezt a két lekérdezést kéne összevonni egybe (táblák szerkezete nélkül nem tudunk tippelni, rakd fel ide az érintett táblák describe-ját, a táblák kapcsolatainak leírását, és a már említett explain is hasznos lenne)
- nem ismerem a pdf lib-et, lehet nem sokat segít, de átláthatóságban mindenképp jobb ötlet a pdf generálást és a lekérdezést különvenni, a query-k eredményét előbb egy tömbbe rakd össze, majd azon fuss végig és csináld meg belőle a pdf-et, ezzel azt is kizárhatnád, hogy a pdf generálás adja-e a nagyobb időket, vagy a lekérdezés (de javasolt mérni inkább)
Egyéb tippek:
- mysql helyett mysqli-re érdemes átállni, ha lehetséges (nem csak a függvényt érinti mint változás, de megéri, főleg, hogy már teljesen elavult)
- nem sokat lehet vele spórolni, de érdemes lehet javítani (egy mozdulat): vannak változók a while-ban, amiket mindig újra értékkel látsz el, de a futás alatt nem változnak (pl.: $keret), ezt ki lehet rakni a while-on kívülre is ha jól látom (nem néztem át tüzetesebben)
- tabulátor használata sokak életét megkönnyíti, ahogy a code-ként való közzététel is (használd a < code > tag-et)
- hosszú távon, nagy táblázatoknál, sok sornál megfontolandó a pdf-et nem php-vel generálni, hanem valamilyen parancssoron keresztül elérhető eszközzel, külön daemon-ban, pl.: fent leírt módon legenerálod a tömböt, lerakot egy .html fájlba, a .html fájlokra pedig cronnal fut egy html->pdf átalakító (lehet mappában fájl jelenlétét vagy db-ben a munka sikerességét ajax-al ellenőrizni, ügyfélnek akkor letölthetővé tenni, ...), ezzel ha a pdf generálása a nagy időigényt adó rész azt csökkentheted, a php-s pdf generálás önmagában alap esetben is idő- és memória igényes tud lenni amennyire láttam
- A hozzászóláshoz be kell jelentkezni
Amennyire sikerült megértenem: A while egy SQL joint valósít meg. Szóval át kellene írni az egészet egy esetelg több selectre meglátásom szerint. :)
- A hozzászóláshoz be kell jelentkezni
Na, azt az egy selectet nem biztos hogy szeretném karbantartani :D
Egyébként megoldás, persze.
Ahogy egy stored procedure is megoldás lenne, ha a mysql tudna ilyet.
--
Gábriel Ákos
http://ixenit.com
- A hozzászóláshoz be kell jelentkezni
Stored procnak vannak nagyon szép hátrányai:
1. Nehéz debugolni
2. A verziókezelése nem megoldott.
3. DB függő.
- A hozzászóláshoz be kell jelentkezni
viszont legalább sok helyen biztonságosnak tartják...erre mit válaszolsz? (kérdezem úgy, hogy én is rühellem a 3 pontodból 2-vel való szívás után)
- A hozzászóláshoz be kell jelentkezni
Biztonságos? Mihez képest? Egy tárolt eljárásban is lehet security hiba, amit ügyesen bevitt adattal triggerelni lehet.
- A hozzászóláshoz be kell jelentkezni
Igaz, lehagytam az -abb részt, biztonságosabb.
- A hozzászóláshoz be kell jelentkezni
mysql alatt a php mysql extension-re vagy magára a mysql adatbázis kezelőre gondoltál? az adatbázis kezelő miért ne tudna tárolt eljárásokat? a php mysql extension nem kezeli őket jól, vagy vált mysqli-re, vagy workaround-ként minden tárolt eljárás után reconnect (NE!)
- A hozzászóláshoz be kell jelentkezni
Érdekes (fel kéne találni hozzá az infochológia nevű áltud interdiszciplinát és abból megélni) hogy a triggerbe/tárolt eljárásba többet szokás belelátni, mint amire használni érdemes, a view-ba meg kevesebbet (tán mert túl könnyű használni, az egyszerűség meg nem tűnik korszerűnek).
Pedig pl. az ilyen förtelmek részeredményeinek view-kba szalámizása rávezethet, hogy hol szeret a cápa.
- A hozzászóláshoz be kell jelentkezni
Miben különbözött volna az, ha a fentiekben view-kat használtak volna? (nem álkérdés)
Legtöbbször azt látom, hogy a view-kat csak arra használják, hogy a query-ket egy helyen tartsák, és schema változtatásakor lehessen ellenőrizni, hogy törik-e valami.
- A hozzászóláshoz be kell jelentkezni
Feltételezve, hogy nem tudja a kérdező, hogy mire/hogyan működik az explain, a joinolt részek külön külön view-ba emelése és lekérése, aztán azok joinolása ad támpontot arra (szegény ember explainje), hogy már az sql húzza be a kéziféket és kb. hol, mikor, vagy a burkoló kód ad az egésznek egy nagy pofont.
És ezzel nem azt mondom, hogy mindenkinek ezt a tanácsot adnám, vagy én ezt tenném - de volt idő, amikor pontosan ezt tettem, más motoron, tudatlanul; sőt később, más hoszton tudva, de jogok híján.
(Persze a view tökéletes alternatívája az sql chunkok kopipésztje, de abba pár lépés után belevakul az ember.)
- A hozzászóláshoz be kell jelentkezni
A fenti két query-re nekem feleslegesnek tűnt a view, de ha jól értem explain helyettesítésre, átmenetileg, általánosan javasoltad, de nem értem mire gondolsz az alatt, hogy túl keveset látnak bele a view-kba, én pl. arra használom, ha egy select több helyen is van használva, akkor mehet view-ba (ritkán futok ilyenbe bele), illetve láttam már a leírt módon használva, schema változtatáskor törések ellenőrzésére.
- A hozzászóláshoz be kell jelentkezni
Ah, ok, nem értettem a kérdésedet.
Csak annyit akartam mondani, hogy valamiért a view úgy kövesedett meg, mint "valami, amit akkor hozunk létre, ha már ezer helyen futtatjuk kb. ugyanazt az sql-t, és már unjuk szétmásolgatni"
Sokáig azt hittem, hogy csak a kollégáim vakfoltjába esik, de nemzetközi portálok is azt bizonyítják, hogy az utolsók között jut az észbe, ha izoláció vagy az érdemi szelektív rész láthatóvá tétele a cél.
(Másrészt (amit végképp nem értek) hemzsegnek körülötte a mítoszok: egyesek "olvasták", hogy a view egy fizikai tábla, szinkronizált tartalommal, másoknak "megtanították az iskolában", hogy a literálhoz képest hatalmas a többletigénye, vagy pont ellenkezőleg - és ezek csak a leggyakoribbak.)
- A hozzászóláshoz be kell jelentkezni
Nekem volt aki azt mondta, hogy a view-k automatikusan index-elődnek. Sok a mítosz, az biztos, szerintem ez is azért van, mert nem tudják mire is való igazából, akkor biztos erre vagy arra.
- A hozzászóláshoz be kell jelentkezni
A view-val az a baj, hogy magára a view-lekérdezéskor nem tudsz indexet használni. Legalábbis mysql-nél így van ha jól tudom.
Pl.
select * from szamla sz
left join szamla_tetel szt on szt.szamla_id=sz.id
where sz.datum='2016-12-09'
Itt szépen működik az index ha indexelve van a szamla tábla datum mezője.
create view szamla_v as
select * from szamla sz
left join szamla_tetel szt on szt.szamla_id=sz.id
;
select * from szamla_v
where datum='2016-12-09'
Itt viszont nem (viszont ha a szamla_tetel tábla szamla_id mezőjén van index azt használja).
- A hozzászóláshoz be kell jelentkezni
Ilyenkor mindig elmorzsolok egy könnycseppet, milyen szerencsés vagyok, hogy nem PHP-s vagyok, és nem kell ilyen () kódokat karbantartanom.
Fuszenecker Róbert
- A hozzászóláshoz be kell jelentkezni
Ez abszolúte nem PHP kérdése, ez simán 1.0 junior által elkövetett kód.
Java-ban is pont ilyen lenne.
--
Gábriel Ákos
http://ixenit.com
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Persze, ez így van.
Mindenesetre én a PHP kódot – akármilyen szépen is van megírva – csúnyának tartom.
Ez szimpla esztétikai kérdés.
És mint tudjuk: de gustibus non est disputandum.
Fuszenecker Róbert
- A hozzászóláshoz be kell jelentkezni
Anno Delphi3-ban is született ilyen kód, a button5_onclick()-ben. Ez nem php és mysql kérdése.
Nálunk is dolgozik olyan, aki "csak" lexikálisan ismeri a nyelvet, nincs önálló ötlete. De ennél ők is szebb kódot írnak...
- A hozzászóláshoz be kell jelentkezni
"Nálunk is dolgozik olyan, aki "csak" lexikálisan ismeri a nyelvet, nincs önálló ötlete"
A tiszta kód nyelvfüggetlen.
- A hozzászóláshoz be kell jelentkezni
Ez de tetszik :)
- A hozzászóláshoz be kell jelentkezni
[Feliratkozás]
- A hozzászóláshoz be kell jelentkezni
Ha ennek az újraírására nem allokálnának időt, vagy az elkövető még ott dolgozna, futnék. Ez elég durva, bocs az off-ért.
- A hozzászóláshoz be kell jelentkezni