Elmélet kategória bejegyzései

SQL SERVER 2016 Bulk insert optimalizáció – megoldás

Az előző postban írtam a bulk insert működésének módosulárásól és arról, hogy nincs megoldás. Most helyesbítenék, van megoldás, több is. A hivatalos, már régóta, csak nekem és még néhány embernek nem sikerül belefutni és a workaround.

A postban maradjunk a hivatalos megoldásnál, ennek a neve: Trace Flag 692. Hogy pontosan mi is ez, azt a hivatalos doksi elmondja itt, a lényege, hogy kikapcsolható az újfajta működés. Ha szükséges kikapcsolni, célszerű az SQL Server startup paraméteri közé betenni, de azonnal életbe lép globálisan, ha kiadjuk a dbcc traceon (692,-1) parancsot.

Leelenőrizni a dbcc tracestatus paranccsal tudjuk, hogy milyen trace flag-ek vannak éppen bekapcsolva.

 

Akit érdekel itt még talál infót az SQL Server 2016 Bullk load-ról.

Reklámok

SQL SERVER 2016 Bulk insert optimalizáció

Az SQL Server 2016-ban a bulk insert gyorsabb lett. Persze nem ingyen.
A gyorsulást úgy érik el, hogy 1-1 bulk insert-et érintő page-en több szabad helyet hagy az SQL szerver, mint eddig, arra számítva hogy még érkezik oda sor.
Nagy mennyiségű adat betöltésénél ez jól jön, de kis mennyiségnél azt látni, hogy jelentősen megnő a db mérete, mert sok üres hely marad a page-eken.

Ráadásul ez a működés nem befolyásolható, nincs visszafele kompatibilitás, stb.
Útálom az ilyen visszafele nincs kompatiblitás változtatásokat, ráadásul megint beigazolódott, a kevesebb feature kevesebb gond elmélet.

 

Üzleti logika a tárolt eljárásban

Sokat feszegetett kérdés, két szélsőséges nézettel:

  • Az üzleti logikát soha nem tesszük SQL-be, mert …
  • Az üzleti logikának az SQL-ben a helye, mert …

Több éve fejlesztek üzleti logikában gazdag és üzleti logikát mellőző adatbázisokat is.
Ez idő során az alábbi előnyökkel és hátrányokkal találkoztam.

Előnyök:

  • Biztonságosabb:
    • Nincs SQL injection
    • Csak azokhoz az adatokhoz fér hozzá az alkalmazás, amit a tárolt eljárás visszaad
  • Kevesebb SQL hívás, összesítve kisebb erőforrás használat:
    • Több SQL hívást egy tárolt eljárás le tud futtatni. Pl olyan hívás, amit egy select-el nem szolgálható ki.
  • Rövidebb, szerver oldali tranzakciók:
    • Egyik alaptétel, hogy egy tranzakció legyen olyan rövid, amennyire csak lehet. A kliens oldalon indított tranzakció sosem lesz olyan rövid, mint a szerver oldalon indított.
  • Csak azok az adatok hagyják el az adatbázis szervert, amire szükség van
    • Az érzékeny adatok, mint pl. jelszavaknak soha nem kell kikerülnie az DB szerverről
  • Nem kell az alkalmazás fejlesztőnek az adatbázissal vesződnie:
    • Megkapja az adatot és dolgozik vele
    • Nem kell sémákat terveznie, megteszi az, aki ezt jobban tudja

A fentiek közül szerintem a biztonság és a teljesítmény a legnagyobb előnyei.

Hátrányok:

  • Egy modern nyelvhez képest szegényes a T-SQL:
    • Nincsenek osztályok, tömbök, stb.
  • Körülményesebb a verziókezelés:
    • SQL szerverre egy verziókezelőt sokkal bonyolultabb és drágább ráépíteni, mint egy mai modern programozási nyelvre
  • A fejlesztési idők lassulhatnak:
    • Mivel a nyelv szegényes, így nehezebben olvasható kódok születnek
  • Kevesebb az SQL fejlesztő, nehezebb pótolni őket:
    • Értelemszerűen, mivel kisebb a piaca ennek a szakmának, így kevesebb munkaerőt találni
    • Mivel kevesebb a fejlesztő, így hamarabb lesz a fejlesztő a szűk keresztmetszet, mint a DB szerver. Viszont, ha nincs SQL fejlesztő, akkor hamarabb lesz a DB a szűk keresztmetszet
  • Adatbázis szervert skálázni körülményesebb és drágább, mint egy alkalmazás szervert
  • Nehezebb az alkalmazást átmigrálni egy másik adatbázis kezelőre
  • Többnyire csak az SQL fejlesztők tudják, hogy mi történik egy-egy tárolt eljárás hívása során

A fentiek közül szerintem a kisebb munkaerő piac és az esetleges fejlesztési idő megnövekedése a legnagyobb hátrányai.

 

Nincs minden teljesen úgy, ahogy fentebb írtam

Ilyen pl, amikor azt írtam, hogy a T-SQL nyelvezete szegényesebb. Ugyanis az SQL szerver lehetővé teszi, hogy pl: C# kódot használjunk CLR integrációval. Egy CLR módosítása viszont újabb problémákat vet fel, ezért ezzel és az ehhez hasonló a ténnyel egyszerűsítettem az előnyök és hátrányok során.

 

Mindenki használ üzleti logikát SQL-ben, ilyeneket mint:

  • NOT NULL constraint
  • Foreign key constraint
  • Unique constraint
  • Check constraint

Ne feledjük, hogy a triggerek, function-ök is hordozhatnak üzleti logikát, ami szintén SQL.

Jellemző még, ha SQL-ben a logika, akkor SQL-t kell optimalizálni, ha alkalmazásban, akkor alkalmazást teljesítmény problémák esetén. Ha keresztbe kell optimalizálni, akkor ott valami jó eséllyel rosszul van tervezve.

 

A nagy kérdés, hogy hol jobb a logika?

Szerintem ez nem olyan fekete-fehér szituáció, ahol egyértelműen ki lehet jelenteni, hogy A vagy B helyen, ezért is lehet ez hitvita kérdése. Mindenki az fogja fújni, amelyik részen fejlesztett, vagy amivel jobb tapasztalata van. Ami viszont biztos, hogy ha megkérdezek két embert, hogy szerinte mi az üzleti logika, más magyarázatot adnak rá.

Én azt gondolom, hogy erősen alkalmazás függő, hogy A, B, esetleg mindkét hely jó lehet. Pl.: egy számlázó rendszerben a tárolt eljárásokban tökéletes helye van az üzleti logikának.

 

Ha a tárolt eljárásban van az üzleti logika, akkor kell e API szerver? Lehet e az adatbázis szerver az API réteg is egyben?

Nekem az a tapasztalatom, hogy kell API szerver, mert:

  • Tud (elő)validálni input adatokat
  • Át tudja alakítani a tabuláris adatokat a megfelelő formára (pl.:JSON, amit a fejlesztők nagyon szeretnek. Bár SQL 2016-tól támogatott a JSON kimenet, meg van CLR is, de ezektől most tekintsünk el)
  • Ha elosztott adatbázisokból kell adatokat kikérni, akkor összefésülheti azokat a megfelelő formára