Tárolt eljárások vs LINQ
2015-01-25T15:45:24+01:00
2015-01-26T21:30:39+01:00
2022-07-19T03:57:40+02:00
  • Annak ellenére, hogy nem vagyok ORM/Hibernate fan, azért a Hibernate nagyon is jól konfigolható, testre szabható. Másrészt a hibernate nem zárja ki, hogy native query is fusson a problémás részeken. Sőt, vannak DB közelibb mapperek (MyBatis), azokat is lehet akár Hibernate mellett is használni, ill. keresések gyorsítására vannak kiegészítő libek, pl. Hibernate Search Lucene indexekkel. Default használatban persze nem a legoptimálisabb eredményt nyújtja, ez igaz.
    Mutasd a teljes hozzászólást!
  • Ez szimplán fegyelmezettség kérdése.... anno még Magyarországon dolgoztam olyan rendszerekkel ahol majdnem a teljes üzleti logika le volt nyomva a DBbe, és nem nagyon volt gond. Egyszerűen csak le volt szabályozva, hogy ki, mikor, hogyan nyúlkálhat bele az adatbázisba.
    Mutasd a teljes hozzászólást!
  • Na de ez ugyanaz az eset mint amikor mondjuk a szarul designolt hibernate berant kismillio felesleges joint a lekerdezesbe, aztan olyan tetu lassu lesz mint a halál.
    A mostani projektemben konkrétan ez a fő szenvedés forrása..abszolut semmi kontrollunk nincs a query felett.

    Összegzésképpen itt is elmondható, hogy mindent lehet jól és rosszul is csinálni :)
    Mutasd a teljes hozzászólást!
  • És még nem említetted azt amikor a tárolt eljárás hívogat tárolt eljárásokat, esetleg execute statement  (jól emlékszem?) parancsokat. Én amikor legutóbb láttam egy ilyen rendszert, volt benne 700 tábla, cirka 2500 trigger és tárolt eljárás. Aztán a táblák különböző prefixet kaptak, attól függően hogy melyik komponens/modul használja őket. Folyamatos fejlesztés néha odáig fajult hogy egy egy tábla átkerült a közösbe, ami egyik komponens se, így kapott egy "közös" prefixet. Igen ám, de a tárolt eljárásokat sok idő lett volna átírni, ellenőrizni, így létrehoztak neki egy viewt a régi nevén. Gyönyörű lehetett debugolni amikor mondjuk az egyik SP abba a Viewba akart írni.
    Miután egy ilyen "rendszert" valaki el tud engedni, többet eszébe se jut a tárolt eljárás.
    Mutasd a teljes hozzászólást!
  • Azért ez is eléggé kétélű dolog. Semmi nem olyan gyönyörű, mint amikor egy ilyen 92 különböző táblákból egy ezer sor fölötti tárolt eljárás szedi össze az adatokat és azt kell kioptimalizálni mert tetűlassú. Különösen akkor szép a dolog, ha kellően komplex logika is van a dolog mögött ami pár szép kis temp táblát, esetleg pár common table expression-t is jelent.

    Az meg aztán maga a gyönyör amikor van egy jó kis magas szintű nyelven írt BL e fölött ami vagy 10 szép kis tárolt eljárást hívogat egymás után különböző feltételek teljesülése esetén, egyenként vagy 6-8 paraméterrel. Még szebbé tudja tenni a dolgot, ha ebbe még egy-két trigger is beleszól, lehetőleg úgy hogy egy táblán van több is belőle...
    Mutasd a teljes hozzászólást!
  • Jobb DBMS-ekben erre a célra materialized view-t használ az ember, mert az effektív ugyanezt csinálja, csak "magától" frissül.
    Mutasd a teljes hozzászólást!
  • Ugyanakkor ha ezt 92 kulonbozo tablabol kell osszevadaszni mindenfele kacaifantos modon, akkor mar abszolut indokolt lenne SP-t hasznalni.

    Egy lehetoseg amit lattam mukodni hasonlo esetben: a "master" adatok szepen normalizalt tablakban, ezekbe irunk es minden modositaskor egy trigger aktualizalja az erteket a denormalizalt tablaban, amit hasznalunk pl. a nagy entitaslista megjelenitesehez.
    Mutasd a teljes hozzászólást!
  • A lekerdezesek komplexitasa nagyon fontos tenyezo - a mostani projektben epp azzal szenvedunk, hogy van par nagyon bonyolult kalkulacio, amit az ORM teljesen elszurt, es istentelen rossz a performancia.

    Pedig az adattomeg abszolut kezelheto (partizezer recorddal kell buveszkedni.) Ugyanakkor ha ezt 92 kulonbozo tablabol kell osszevadaszni mindenfele kacaifantos modon, akkor mar abszolut indokolt lenne SP-t hasznalni.
    Mutasd a teljes hozzászólást!
  • Elég sokmindent leírtak itt amiknek nagy része szerintem igaz is. 
    Én azt emelném ki hogy mivel a Linq-val megírt kódok generált kódok (Lehet akár EF vagy LinqToSql is) mindig lesz egy performance overhead. Az ORM mapperek jelenleg még tudásban eléggé elmaradottak azokkal az igényekkel szemben amiket egy tárolt eljárás lazán tud kezelni. 
    Én per pillanat nem használok EF-et aktívan úgyhogy valószínűleg pár elemben nincs igazam de pl. amikor utoljára néztem:
    - nem lehetett tábla paramétereket használni.
    - kötegelt feldolgozás nagyon nehézkes volt.
    - a left joint nem ismerte és nagyon kacifántos kóddal lehetett kikerülni
    - query hinteket nem lehetett használni
    - nem volt lehetőség a tempdb kihasználására

    Ezzel szemben a tárolt eljárásoknál mivel SQL kódot írsz, teljes kontrollod van affelett hogy mi történik ha értesz hozzá. 

    A hangsúly azon van hogy ha értesz hozzá. Egy ORM réteggel ellátott alkalmazást sokkal hamarabb elkészíthetsz mint egy olyan ami tárolt eljárásokkal dolgozik és sokkal egyszerűbb is lesz hosszú távon a managelése (Pl. nem triviális egy jó kis CI-t beállítani akkor ha tárolt eljárásokat használsz).

    Viszont ha nagy terhelés van és a sebesség létszükséglet, nem nagyon látok pozitív érvet az ORM rendszerek mellett. 

    Én azt mondanám hogy a projectek 80%-át simán készítheted ORM-el mindenféle megkötés nélkül. A maradék 20% a nagy performancia igényű rendszereket jelneti. Ott az esetek nagy részében öngyilkosság lenne egy ORM rendszer használata.
    Mutasd a teljes hozzászólást!
  • - Legalábbis az EF képes arra, hogy ellenőrizze a modelled és az adatbázisod közötti konzisztenciát.

    Éppen úgy futásidőben, mint egy tárolt eljárás esetén. Ráadásul a dolog abban az értelemben nem ér sokat, hogy akár a program futása közben is változhat a séma, amit nyilván az EF sem fog észrevenni, csak amikor valami műveletet akar végezni rajta, és az nem megy. Megint csak pont úgy, mint egy tárolt eljárás esetén.

    Ezzel szemben egy tároltakra épült rendszerben simán megcsinálhatsz olyat hogy megváltoztatsz egy mezőnevet a táblában, és ezt az SP-k csak akkor veszik észre, ha megpróbálod futtatni őket.

    Ha valami szuperbéna adatbáziskezelőt használsz, akkor igen. A jobbak nyilvántartják a tárolt eljárásokban, nézetekben, stb. hivatkozott táblákat, mezőket, stb. mint egy idegen kulcs esetén, és nem engedik átírni vagy törölni azt a mezőt, amire van élő hivatkozás (kivéve ha CASCADE-dal utasítod erre, ill. az érintett sémaelemek törlésére őket).

    Ezen kívül lehet általában kérni a tárolt eljárások újrafordítását a sémaváltozások esetén, ami éppen úgy, mint a program újrafordítása, kidobja azonnal, ha valamelyik tárolt eljárásban érvénytelen mezőre van hivatkozás, vagy olyan műveletet deklarál egy mezőn egy tárolt eljárás, ami nem érvényes az adott típusra.

    Ezen kívül az, hogy a program automatikusan ellenőriz és/vagy frissíti a sémát egészen csak addig jó, amíg egy egyfelhasználós helyi programról van szó. De pl. hálózati környezetben, ahol elvárás lehet, hogy ugyanannak a programnak több különböző verziója, vagy több eltérő (akár más-más nyelven készült) program is együtt dolgozzon ugyanazon az adatbázison, pont az okozza a problémát, ha egy program kényszeresen valamiféle konzisztenciát akar fenntartani a saját kódja és az adatbázis sémája között, függetlenül attól, hogy az a helyes működés szempontjából szükségszerű -e vagy sem.


    A fentiektől függetlenül a legnagyobb baj bármilyen nyelvi szintre integrált lekérdezéssel az, hogy direkt arra bátorítja a felhasználót, hogy sértse meg a "separation of concerns" alapelvét, valamint azt, hogy ne válassza el egymástól élesen, külön rétegekbe a fizikai és a logikai adatmodellt, illetve adatelérési réteget. Amik mind rontják a program refaktorálhatóságát és átláthatóságát.

    Persze ezeket a hibákat a LINQ hiányában is el lehet követni, illetve a LINQ-t is lehet a fenti elvek betartása mellett használni. De ettől még igaz marad, hogy a LINQ kifejezetten egyszerűvé és kézenfekvővé teszi ezen alapelvek megsértését a programozó számára.
    Mutasd a teljes hozzászólást!
  • Ha változtatsz a modelleden, azaz A mezőnevet B-re nevezed át újra kell futtatnod a modell készítést, különben az első indításnál lehal, mert nem tudja felépíteni a viewokat. Ilyenkor a VS végigmászik a kódodon és átírogatja az új mezőnévre. Ezzel szemben az SP-k tényleg csak futtatáskor tudják meg hogy valami hiba van.
    Mutasd a teljes hozzászólást!
  • Ezzel szemben egy tároltakra épült rendszerben simán megcsinálhatsz olyat hogy megváltoztatsz egy mezőnevet a táblában, és ezt az SP-k csak akkor veszik észre, ha megpróbálod futtatni őket.

    Nem fordítva? Én nem vagyok jártas .NET-ben, de a LinQ nem a programod (kvázi exéd) része? Ha igen, akkor mi akadályozhatná meg az adatbázis módosítását? Elindítod az exe-t és jobb esetben elhasal vagy akkor még nem, hanem amikor a program azon részén dolgozzunk. Sokszor pont az általad keltett vitákban szokott érvként előjönni, hogy a típust nem ellenőrizzük állandóan, csak fordításkor. Ebből nekem pont az következne logikusan, hogy az adatbázist sem kezdi el vizsgálgatni az exe, csak amikor csatlakozol hozzá és pont abban a táblában keresnél és nincs meg a mező.

    A Firebird meg pont nem engedi hogy olyan mezőt változtass meg, amit egy SP használ. Mysql esetén meg lehet ilyet csinálni, mssql-t meg megint nem ismerem. De általánosságban nem jelenthető ki, hogy mindegyik rendszerben lehet módosítani a mező nevét, miközben használatban van egy SP-ben.
    Mutasd a teljes hozzászólást!
  • A LINQ-t ".NET-ben" (C#,VB stb) írod, a tárolt eljárást SQL-ben. LINQ esetén az adatok kezelésének a logikáját áthozod a klienshez, míg a másik esetében marad az adatbázisban.
    A LINQ sok mindent elrejt a programozó elől, nem mindig úgy csinálja meg ahogy gondolnád, az SP-k ehhez képest egyszerűbb jószágok.
    LINQ-val szoktam megoldani az insert,update,delete,select négyest ha néhány elemről beszélünk, SP-be kerülnek azok a feladatok amik nagyobb kapacitást igényelnek pl.: tömeges update
    Mutasd a teljes hozzászólást!
  • Többféle szempont jöhet számításba. Általában véve azt lehet mondani, hogy a linq akkor igazán jó, ha összetett logikát kell leprogramozni, a tárolt pedig akkor, ha nagy tömegű adaton kell viszonylag egyszerű műveleteket végrehajtani.

    Ezen túl elég sok szempont játszhat:
    - A linq esetén nagyon nem árt, ha tudod hogy milyen SQL generálódik - különben csúf meglepetések érhetnek. Általában egy EF elég jó SQL-t produkál, de néha nagyon nem mindegy hogy hogy fögalmazod meg a query-t. Persze egy SQL-nél sem árt néha tudni, hogy milyen exec plan lesz a végén végrehajtva...
    - Linq-ra épített BL-t tudsz úgy unit teszelni, hogy nem kell hozzá adatbázist csesztetni.
    - Legalábbis az EF képes arra, hogy ellenőrizze a modelled és az adatbázisod közötti konzisztenciát. Ezzel szemben egy tároltakra épült rendszerben simán megcsinálhatsz olyat hogy megváltoztatsz egy mezőnevet a táblában, és ezt az SP-k csak akkor veszik észre, ha megpróbálod futtatni őket.
    - Tárolt eljárások esetén csinálhatsz olyan biztonsági beállításokat, hogy a programodnak csak az SP-k futtatására van joga, de Pl. selectet végrehajtani nincs. Így elvben biztonságosabb lehet a rendszered.
    - Viszont egy olyan rendszert, ahol linq-ra épül a BL sokkal könnyebb debuggolni mint egy olyat ahol ide-oda kell ugrálni az SP-k és a .NET-es kód között.

    És egy rakás másik, ami most nem jut az eszembe...
    Mutasd a teljes hozzászólást!
  • Azért zavaros a kérdésem, mert a külföldi oldalakon kutatgattam és erre nem találtam egyértelmű választ. Tehát akkor az egyik adatbázis oldali a másik pedig nem. Most már ez is tiszta sor!
    Egyébként azért tettem, mert külföldi oldalakon is találtam ehhez hasonló oldalt:
    Adatelérés: LINQ vs. Tárolt eljárás

    Viszont konkrét példát nem találtam rá,hogy mit is akarnak kihozni ebből.
    Mutasd a teljes hozzászólást!
  • Nem vagyok nagy C# mágus de a Linq egyfajta lekérdező "nyelv" amit nem csak bindingsource-ok hanem listákra(és még sok másra) is lehet alkalmazni. A tárolt eljárások azok az adatbázis oldalon mennek végbe. A linq nincs adatbázis oldalon ergo, nem teljesen értem a kérdést. A linq-val a tárolt eljárásokat tudod managelni, de a linq nem tárolt eljárás.
    Mutasd a teljes hozzászólást!
  • Sziasztok. Az lenne a kérdésem milyen konkrét esetben alkalmazunk tárolt eljárásokat, illetve LINQ lekérdezéseket. Tudtommal a tárolt eljárásokat olyan automatizált folyamatok ellátására lehet használni, ami így nem igényel emberi felügyeletet (mondjuk egy adott adatbázis tábla karbantartása felügyelet nélkül - pl. autókereskedés esetén a 10 évnél idősebb autók automatikus törlése valamely táblából). A gyakorlatban LINQ eljárást is alkalmaztam már. De mégis milyen konkrét példa van arra amikor kifejezetten csak az egyiket vagy csak a másikat lehet alkalmazni? Ugyanakkor előfordulhat,hogy ugyanazt a feladatot mindkét módon végre lehet hajtani, ugyanakkor adott esetben LINQ helyett tárolt eljárást alkalmazzunk? Elnézést, ha kezdőnek tűnök ebben a témában, várom mindenki válaszát. Köszönöm!
    Mutasd a teljes hozzászólást!
abcd