Van egy jó kis SSIS csomagunk, ami nagyjából semmi mást nem csinál, csak adatokat tesz át egyik szerverről egy másikra. Nincs benne különösebb logika, nincs benne transzformáció, tényleg 99%-ban az a belseje, hogy truncate table xy; insert into másikszerver..tábla select from ezaszerver..tábla;
Mivel az Integration Services csomagokat nem lehet igazából merge-elni semmilyen verziókövető rendszerben, ezért megpróbáltam áttenni sima TSQL-be.
Maga a script viszonylag gyorsan meglett, ahogy említettem, nem volt bonyolult. Kicsit trükközni kellett az identity insert miatt, kicsit trükközni kellett a tesztelésnél, de megvolt.
Aztán lefuttattam egy staging tesztet és kiderült, hogy felesleges volt a munkám. Ugyanis annyira lassú volt a scriptem, hogy csak pislogtam. Az SSIS csomag lefutott 2-3 perc alatt, a scriptem laza 20 perc alatt, pedig még egy kicsit optimalizáltam is amit tudtam.
Nem fért a fejembe, hogy ez miért működhet nagyjából nyolc-tízszeres szorzóval. Egyszerűen nem logikus ezért elkezdtem túrni a netet. Három dolog merült fel és sajnos mindegyik az SSIS javára viszi el a mérleg nyelvét.
Párhuzamos végrehajtás
Először is ott van, hogy az SSIS tud párhuzamosan végrehajtani, míg TSQL-ben ez ugyan nem lehetetlen, de hivatalosan nincs ilyen. Itt most nem igazán lekérdezésekre és az azokban elérhető párhuzamosításra gondolok, hanem konkrétan párhuzamosan végrehajtott insertekre, párhuzamosan végrehajtott külön utasításokra. (MAXDOP-pal kicsit játszhatunk, de a szerverhez nincs ilyen szinten hozzáférésünk.)
Kis trükközéssel megoldható, hogy bizonyos utasítások párhuzamosan fussanak le TSQL-ben, de ez trükk. Hivatalosan nem támogatott, ráadásul elég ronda megoldás.
SSIS – TSQL : 1:0
Logolás
Második a tranzakciós logok kezelése. A cél adatbázis az éles, tehát természetesen full recovery model van rajta. Amikor a TSQL script fut, akkor a szerver logol, mint a katonatiszt. Az Integration Services ellenben megkerüli ezt a részt és akármit is mond az adatbázis, csak minimálisat logol. Nem mondom, hogy a simple-t használja, de az biztos, hogy nem azt, amit az adatbázison én látok.
Készítettem pár tesztet és az fn_dblog
segítségével kiderült, hogy ugyanolyan adatmennyiségnél az SSIS kb. 20-50%-kal kevesebbet használta a logokat (az én esetemben). Ezzel természetesen megint az SSIS lesz gyorsabb, hiszen kevesebb log kevesebb írást jelent, kevesebb írás meg gyorsabban lefut.
SSIS – TSQL: 2:0
Distributed transactions
Harmadikként pedig érdemes megemlíteni, hogy a csomag egy staging szerverről tenné át az adatokat az éles szerverre. Tehát a TSQL linked servereken keresztül működne és kiderült, hogy ha „table or view” a data flow kiindulópontja, akkor az SSIS nem használ DTC-t. Ezzel megint csak időt nyer. Át lehetne állítani fast loadra, viszont azzal is lehetnek gondok. A lényeg, hogy a jelenlegi formájában megint csak kicsit „csal” az SSIS csomag végrehajtásnál és ez újabb másodperceket ver a TSQL-re.
SSIS – TSQL: 3:0
Egyelőre feladom
Körül lehetne még nézni és lenne még pár ötlet vagy opció, amit ki tudnék próbálni. Egyelőre ennyi időm volt a feladatra, és ezt ebben a formában el kell engednem, egyelőre marad az Integration Services csomag. Úgy néz ki, hogy ezeket az SSIS csomagokat elég jól összerakták és kioptimalizálták, a TSQL-nek ebben az adott feladatban esélye sincs a nyomába érni.
Az eredeti problémára, a verziózásra, branchek kezelésére meg ki kell találnom valamilyen manuális vizuális merge-t. Az sem lesz igazán könnyebben kezelhető, de meg kell próbálni annyira egyszerűvé és egyértelművé tenni, amennyire csak lehet.