Üdv!
Vab egy lekérdezés ami eléggé összetett.
A kérdés, hogy ki dolgozzon. Sql alatt csak join-al lehet megoldani, php-be meg 2 lekérdezés egymásba ágyazva.
Mindkettő elég lassu kimenetet adott sok adatnál. (sok adat: kb 20e az egyik táblába és mindegyikhez 0-max 5 ig a másik táblába (amit joinolni kellene))
pch
- 1610 megtekintés
Hozzászólások
Sokat segítene, ha mutatnál konkrét példát. De általában az SQL dolgozzon, azon lehet mindig faragni és elegánsabb is.
--
Keep it simple, stupid.
- A hozzászóláshoz be kell jelentkezni
Íme:
első tábla: (szamla)
id | nev_id | datum | osszeg | szamlaszam
masodik tábla: (nev)
id | nev
harmadik tábla: (fizet)
id | szamla_id | osszeg | datum
Magyarázat:
Első táblába lévő szamlahoz több kifizetés is tartozhat. ezeket a harmadik táblába tároljuk. A 2. tábla a száma tulajdonos neve.
Lekérdezés:
adott időinvertalumba lévő lekérdes figyelembe véve a fizetést is, a következő lehetőségekkel:
fizetett (1.osszeg=sum(3.osszeg))
nemfizetett (sum(3.osszeg)=0))
részben (1.osszeg<>sum(3.osszeg))
meg persze névszerint, számlaszám szerint
pch
--
http://www.buster.hu
--
- A hozzászóláshoz be kell jelentkezni
SQL, ügyelve a 3. normálformára, indexelve, ahogy itt is mondják:
http://hup.hu/node/73163#comment-804732
--
Keep it simple, stupid.
- A hozzászóláshoz be kell jelentkezni
Indexelve vagyon minden...
fizet tábla:
index: fizet1 | datum1 | szamla_id
szallito tabla:
index: teljesites | brutto2 | vevo_id
vevo tabla:
index: vnev | vnev_id
Lekérdezés (mondjuk a részben fizetett)
SELECT kimszallito.szallito_id, teljesites, vnev, vnev_id, szallitoszam, esedekes, ifnull( szum, 0 ) AS fizet, brutto2, raktar_nev, vont, nyomtat, storno,uzlet ,(brutto2-(ifnull( szum, 0 ))) AS tart
FROM vnev, raktar, kimszallito
LEFT JOIN
( SELECT szamla_id, sum( fizet1 ) AS szum
FROM fizetkiadszallito
WHERE fizetkiadszallito.datum1
BETWEEN '2009-01-01' AND '2009-07-06'
OR fizetkiadszallito.datum1 IS NULL GROUP BY szamla_id ) AS sum_table
ON ( sum_table.szamla_id = kimszallito.szallito_id )
WHERE kimszallito.teljesites BETWEEN '2009-06-01' AND '2009-07-06'
AND szallitoszam LIKE '%%'
AND kimszallito.vevo_id = vnev.vnev_id
AND raktar_id = uzlet
AND uzlet LIKE '%'
AND vont LIKE '%'
AND ifnull( szum, 0 ) <> brutto2
cép mi?
pch
--
http://www.buster.hu
--
- A hozzászóláshoz be kell jelentkezni
egyreszt erdemes lehet a tablakat datum szerint particionalni. masreszt ez a query nem csoda, h lassu. minek keresel ra minden oszlopra raadasul like-al? imho nagysagrendekkel gyorsabb lenne, ha a queryt a bejovo lekeres alapjan epitened fel es a like-ot csak ott hasznalnad ahol szukseges.
udv.:
-szobi.
- A hozzászóláshoz be kell jelentkezni
Szal legyen inkább több query és if-el válogassam le a legördülőket figyelembe véve?
Táblákat hogy particionáljam?
pch
--
http://www.buster.hu
--
- A hozzászóláshoz be kell jelentkezni
http://dev.mysql.com/doc/refman/5.1/en/partitioning.html
a query epitesere emlekeim szerint php alatt is vannak kesz libek, de mind1 is. a lenyeg, h attol fuggoen milyen input parameterek jonnek be, az alap queryhez hozzacsapsz dolgokat. pl. ha van erteke az xxx valtozonak, akkor beleteszed a query-be, hogy and tabla.xxx = '$xxx'; vagy ilyesmi. a like-ot hasznalni meg nem jo, ha csak nem tenyleg szovegreszleteket kell keresned.
udv.:
-szobi.
u.i.: amit irtal, h tobb query es iffel, na, az jo csunya, vegul is csak egy queryd van, szoval azt kell alakitani...
- A hozzászóláshoz be kell jelentkezni
jézusmária.
azt a rengeteg like-ot ki kell szórni a végéről, aztán a 2 dátum intervallumot is összhangba kellene hozni, szerintem sokat segítene (bár így is lehet értelme, de nem látom).
Szerintem írd le és magyarázd meg a struktúrádat, és azt is, hogy mit szeretnél látni.
x
- A hozzászóláshoz be kell jelentkezni
Összhangba nem lehet hozni.
Ugyanis a fizetési intervallum minden kezdő év 01-01 től kell nézni addig ameddig megadja a végdátumot. A teljesítési idő meg a kezdő és a végdátum közt van.
A rengeteg like:
szallitószám: ha egy szállító számot keres akkor a beírt érték, ha üresen hagyja akkor mindet listázza.
Üzlet és a vont is ugyanaz. A vont-nál legördülő menübe adja az értéket igen=1 nem=0 ha nem választ %.
Kis magyarázat még:
A fizetkiadszallito táblába tárolom hogy mikor mennyit fizettek.
Ezt ugye (a fenti idő beállításokkal) össze kell adni.
Ezut joinolom a szallito táblával (itt pedig a teljesítési időt figyelembe véve)
és a szallito összeg-et vonom ki az előbbi összeadással.
És az utolsóba pedig tovább szüröm..
if ($f_fiz=='F'){ $kereses="AND ifnull( szum, 0 ) = brutto2";}
if ($f_fiz=='R'){ $kereses="AND ifnull( szum, 0 ) <> brutto2";}
if ($f_fiz=='N'){ $kereses="AND ifnull( szum, 0 ) = 0 AND brutto2 <> 0";}
if ($f_fiz=='0'){ $kereses="";}
Nem jut eszembe jobb megoldás, de ha létezik ne tarcsátok magatokba!
pch
u.i.:
szal a mezők:
tol dátum - ig dátum
számla/száll |vevö neve | számla/szállítószám | üzlet | összes/fizetve/nincsfizetve/részben | vont-e/nemvont/vont |
a kimenet:
telj.dátum | nev | számlaszám | lej. dát| lejárt napok | tart. | számla bruttó | üzlet | fizetett(F;N;R) |nyomtatott | vont |
--
http://www.buster.hu
--
- A hozzászóláshoz be kell jelentkezni
"A rengeteg like:
szallitószám: ha egy szállító számot keres akkor a beírt érték, ha üresen hagyja akkor mindet listázza.
Üzlet és a vont is ugyanaz. A vont-nál legördülő menübe adja az értéket igen=1 nem=0 ha nem választ %."
akkor már inkább:
if ('' != $_POST['szallitoszam']){
$kereses .= " and szallitoszam like '".$_POST['szallitoszam']."%'";}
vagy vmi ilyesmi. szal ha nincs megadva akkor nem is kell megadni feltételben.
- A hozzászóláshoz be kell jelentkezni
Igen, igazad van, átírtam már mire bepostoltad..
Ugytünik kissé gyorsult...
Köszike az építő hozzászólást!
pch
--
http://www.buster.hu
--
- A hozzászóláshoz be kell jelentkezni
Szerintem az SQL. Nekem azt mondtak az okosok, hogy mindent, amit lehet az SQL vegezzen. Persze inkabb merd le, hogy melyik a gyorsabb es az alapjan valaszd ki a jo megoldast.
Csak egy join van a lekerdezesben, mert akkor amugy egyertelmu, hogy SQL. Az 1 db select lesz, nem kell a kodban ciklussal szervezkedni, stb. Talan egyszerubb.
- A hozzászóláshoz be kell jelentkezni
Elvileg ha normálisan indexeltek az egyesítésben résztvevő mezők, akkor nem kéne lassú legyen. A php-s 2 lekérdezés sorban fut le, az eredményt meg össze kell még fűzzed, ugye?
Én egy indexeket használó joint választanék mindenképpen.
--
Coding for fun. ;)
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy butasag, de lattam mar olyan megoldast, hogy kb evente uj tablat nyitottak a szamlaknak, igy csak annyi sor volt a szamla tablajaban, amennyi szamlat abban az evben kiallitottak es ugyanigy sokkal kevesebb tetel, amivel dolgozni kellett.
Igy viszont a PHP dolgozik többet (táblák létrehozása, stb) De gondolom nem igy gondoltad :)
- A hozzászóláshoz be kell jelentkezni
Gondoltam énis évi uj táblába, csak gyakorlatba rengeteg oda-vissza lépés lenne, míg az adott év összes számlája/szállítója nem rendeződik...
pch
--
http://www.buster.hu
--
- A hozzászóláshoz be kell jelentkezni
Nálam évváltás gomb van, nem kényelmetlen használni...
--
Coding for fun. ;)
- A hozzászóláshoz be kell jelentkezni
Ha a jövőben nőni fog a terhelés, lehet a PHP dolgoztatásával jársz jobban, sokkal könnyeben skálázható (bővíthető több gépesre). Ha egy gépen belül marad a dolog, akkor meg kell mérni, hogy melyik a gyorsabb.
- A hozzászóláshoz be kell jelentkezni
Dehogyis, ne hülyéskedjünk már.
Egyértelműen SQL, ugyanis az erre van kitalálva. A PHP meg egyáltalán nem. Meg lehet benne mindent csinálni, szeretem, használom, de nem erre való.
Monnyuk normálisan meg kell tervezni és meg kell írni, indexelni, explain, stb. Lazán használok milliós rekordszámú többszázmegás táblákat join-olva és gyors.
Skálázódás meg itt abszolút nem játszik, itt egy egyszerű számlázásról van szó himihumi pistike szinten. Ha akkora batár dolog, hogy több szerverre kell pakolni akkor már régen nem a php-mysql vonalról beszélünk, hanem mérnökökről akik megtervezik, kireszelik, etc. Nem mellesleg MySQL cluster is van.
- A hozzászóláshoz be kell jelentkezni
MySQL:
EXPLAIN [EXTENDED] SELECT ...
http://dev.mysql.com/doc/refman/5.0/en/explain.html
sok mindent megmond.
--
"SzAM-7 -es, tudjátok amivel a Mirage-okat szokták lelőni" - Robi.
- A hozzászóláshoz be kell jelentkezni