Ki dolgozzon? (php vs sql)

Ü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

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.

Í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
--

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
--

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.

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...

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

Ö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 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.

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.

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. ;)

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 :)

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.

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.