Archive for May, 2008

Visual Studio Next

Thursday, May 29th, 2008

Rosario-nak hívják a drágámat, áprilisi CTP-nél járunk.
No kérem, ahogy nézem ebből a postból, az architect (kevésbé nagyképűen tervező) cuccok igen ütősek lesznek benne. Ha mást nem, hát a képeket érdemes megnézni, sokat mesélnek, mi várható.

Élet 64 biten

Thursday, May 29th, 2008

Látom Józsi is kóstolgatja a 64 bitet, több-kevesebb sikerrel.
Nekem a cégnél most az egyik feladatom az, hogy a natív, low-level Hook-os és COM-os C++ cuccokat nézzem meg, hogyan fognak majd működni 64 biten.
Kaptam egy DELL 3400-ast, 2 procival, 4 G RAM-mal, 2 HDD-vel, amik RAID1-be RAID0-ba vannak kötve az alaplapi vezérlő segítségével.
Vista és VS 2008 van rajta. Először is, a Vista olyan simán felment rá, hogy csuhaj. De tényleg, mire a gyerekek lefürödtek, már fenn is volt. K. semmi bajom nem volt vele, csodálkoztam is, mert sokaknak gondjuk van a driverekkel. Ebből a szempontból hálás a neves gép. Meg csendes is, féltem, hogy lesz egy hangos desktop gépem, de nagyon csendes.
Ami a legélvezetesebb a vele való munkában, az a C++ fordítás. Közismert, hogy ez piszok lassú dolog. De nem ezen a gépen! Eszméletlen gyorsan hasít, gondolom a RAID1 is sokat dob ezen. Élvezet így fordítani és dolgozni rajta.
Menet közben, ha találok érdekes dolgokat majd leírom.

Mi lesz a .NET Fw. 3.5SP1-ben?

Thursday, May 29th, 2008

Nem kevés, érdemes végigszaladni rajta.

Pl. az Entity Fw. is része lesz, nem kis falat. Vagy a manazsolt exe-k futtatható network share-ről, full trust-tal. Ez elég meglepő számomra, de sok embernek örömet fog okozni, aki nem ismeri a CAS-t, ezért szívott vele.

SQL Server UPSERT variációk 4.

Wednesday, May 28th, 2008

Most jön az a megoldás, amelyik mind között a leggyorsabb, de egyúttal a legkevésbé szép. :)

create proc dbo.UpsertClient4
  @id int,
  @name nvarchar(100)
as
begin try
    insert dbo.Client (id, name) values (@id, @name)
end try
begin catch
    if (error_number() = 2627)
        update dbo.Client set name = @name where id = @id
end catch

Nekiszaladunk az insertnek, ám ha a sor létezik már adott id-vel, akkor visszapattanunk, és jön az update. Csak a constraint violation (2627) esetén jön az update, egyébként újra raise-elni kellene a hibát, ez nincs benne a példában.

Habár normál adatbázisoknál ez a megoldás jóval gyorsabb az előzőeknél, a hibakezelést könnyű elrontani, ezért észnél kell lenni a használata során. De ha a sebesség az úr, ezt a megoldást érdemes választani.

Emlékeztetőül a megoldások futási ideje, a kevesebb a jobb:

procid dur
———– ———–
1 152
2 161
3 164
4 64 <--- 5 186 [/source]

Mi az a Dynamic Data?

Wednesday, May 28th, 2008

5 perces kis videó a témáról.

Valami olyasmi cucc ez, amivel rendkívül gyorsan össze lehet rakni CRUD jellegű adatkezelő website-okat, de teljesen testreszabható módon, template alapon, nem sima kódgenerálással. Érdekes megoldás, de nem tudom mennyire lesz majd használható.

SQL Server UPSERT variációk 3.

Tuesday, May 27th, 2008

Eléggé sok teher van most rajtam, ezért nem iparkodok az upsert cuccokkal, de igyekszek utolérni magam.

A harmadik megoldás már kicsit ravaszabb, SQL Server 2005-ös utasításokat is tartalmaz:

create proc dbo.UpsertClient3
  @id int,
  @name nvarchar(100)
as
set xact_abort on
begin transaction

update dbo.Client set name = @name where id = @id
 
insert dbo.Client (id, name)
select * from (values (@id, @name)) t(id, name)
except
select * from dbo.Client as t2 with (updlock, serializable)

commit
go

Az except és az intercept halmazműveletek jól jönnek, hogy az update és az insert csak a számára szükséges adatokat kapja meg. Az update-nél nem használtam, hisz ha egy sor nincs benne a táblában úgyse lehet meg update-elni. Az intercept-tel elő lehetett volna szűrni az adatokat, de minek?
Az insert esetén viszont már nem vagánykodhatunk, ki kell venni a bemeneti halmazból a már céltáblában bennlévő sorokat. (Most, hogy ezt írom eszembe jutott, hogy lehet, hogy ezt is ki lehet sprórolni, ha az IGNORE_DUP_KEY be van állítva a kulcs oszlopra. De valahogy rossz érzésem van ezzel kapcsolatban.)

A példa az előző kettővel ellentétben már nem csak 1 bementi sort képes lekezelni, hanem egy tetszőleges számú bementi halmazt is. Tábla típusú paraméterekkel kiválóan együttműködhet.
A megoldás sebessége kb. az előző kettő szintjén van, de ezt utóbbi többsor-lekezelési lehetőség miatt érdemes megfontolni.

Kamatadó, avagy hogyan romlik a pénzünk a bankban

Friday, May 23rd, 2008

Előrebocsájtom, nem vagyok közgazdász, csak egy egyszerű mérnök, aki időnként naívan gondolkodik a világ dolgairól, de legalább igyekszik gondolkodni.

Számolgattam kicsit, mit csinál a pénzem a bankban. Tegyük fel van 5m Ft-om, amit sokáig tudok nélkülözni, mondjuk 10 évig, ami után már nincs kamatadó a befektetésekre. Mivel a bankban rövidebb időkre lehet csak lekötni a pénzt (sima bankszámlán, nyilván vannak befektetéseik is), szembesülünk a kamatadóval.
A következő peremfeltételekkel számoltam (mesterséges, de talán realisztikus). 6% infláció, 7% banki kamat, 20% kamatadó, fél éves periódusidő. Nyilván szinte minden paraméter változik, de ezeket mégis csak le kell fixálni, hogy valami kapaszkodónk legyen.

Lássuk, mire jutunk 10 év alatt:

Év	Tőke	Kamatadó		Infláció hatása
0	5,000,000 Ft	0		
0.5	5,138,093 Ft	27,619 Ft		5,147,815 Ft
1	5,280,000 Ft	28,381 Ft		5,300,000 Ft
1.5	5,425,826 Ft	29,165 Ft		5,456,684 Ft
2	5,575,680 Ft	29,971 Ft		5,618,000 Ft
2.5	5,729,673 Ft	30,799 Ft		5,784,085 Ft
3	5,887,918 Ft	31,649 Ft		5,955,080 Ft
3.5	6,050,534 Ft	32,523 Ft		6,131,130 Ft
4	6,217,641 Ft	33,421 Ft		6,312,385 Ft
4.5	6,389,364 Ft	34,345 Ft		6,498,998 Ft
5	6,565,829 Ft	35,293 Ft		6,691,128 Ft
5.5	6,747,168 Ft	36,268 Ft		6,888,938 Ft
6	6,933,516 Ft	37,269 Ft		7,092,596 Ft
6.5	7,125,010 Ft	38,299 Ft		7,302,274 Ft
7	7,321,793 Ft	39,357 Ft		7,518,151 Ft
7.5	7,524,010 Ft	40,444 Ft		7,740,411 Ft
8	7,731,813 Ft	41,561 Ft		7,969,240 Ft
8.5	7,945,355 Ft	42,708 Ft		8,204,835 Ft
9	8,164,795 Ft	43,888 Ft		8,447,395 Ft
9.5	8,390,295 Ft	45,100 Ft		8,697,125 Ft
10	8,622,023 Ft	46,346 Ft		8,954,238 Ft
		724,405 Ft		
				
Nyereség	-332,215 Ft			

A bankban 10 év múlva 8.62M lesz, az adott inflációval számolva viszont 8.95M esetén lennénk nullszaldósak. Azaz nemhogy nyerünk, de vesztünk 330 ezer forintot.
Az a szar a kamatadóban, hogy a kamatos-kamat exponenciális voltát is lapítja, ezért többet ront, mint gondolnánk.

Közgazdász vénájúak, tessék megmutatni, hol beteg a gondolatmenetem, vagy megerősíteni, hogy ilyen szar a helyzet?

SQL Server UPSERT variációk 2.

Thursday, May 15th, 2008

Folytatásként mutatok egy második nekifutást az előző rész problémájára. Ebben elkerültem a felesleges if exists-et, amely miatt egyszerűbb lett az eljárás. Azt vártam egyébként, hogy gyorsabb is lesz, de nem, hisz most is kétszer futunk neki a táblának.

create proc dbo.UpsertClient2
  @id int,
  @name nvarchar(100)
as
set xact_abort on
begin transaction

update dbo.Client with (serializable) set name = @name where id = @id

if (@@rowcount = 0)
  insert dbo.Client (id, name) values (@id, @name)

commit

Az előző megoldáshoz képest itt nem kellett updlock hint, hisz az update elve azt használ az olvasási fázisban (másként a sima update-ek is állandóan deadlockolnának, pont ezért van külön update lock).
A serializable az előző részben részletezett okok miatt kell, azaz meg kell fogni az update-elendő kulcsot, ha létezik a sor, ha nem, hogy a következő insertnek “meg legyen ágyazva a hely”.

SQL Server UPSERT variációk 1.

Wednesday, May 14th, 2008

A konferenciára készülve próbáltam összerakni példákat, hogyan lehet megvalósítani upsert eljárásokat SQL Server 2000, 2005 és 2008 alapon. Ezekre nem volt idő a konfon, ezért most bemutatom őket.

A probléma egyszerű: jön fel a szerverre egy sornyi infó, azt kell beszúrni egy táblába, ha valamilyen szempont szerint nem létezik a sor, vagy ha létezik, frissíteni. Mindezt a konkurens hozzáférések ellen korrektül védve kell megvalósítani.

Az első megoldás a legkézenfekvőbb logikával működik, if exists-szel megnézzük, létezik-e a sor, ha nem insert, ha igen, update. Persze mindezt tranzakcióban végrehajtva. Ez azonban kevés, mert alap izolációs szinten a select elengedi a zárolásokat amint végzett, így lehet, hogy azt látjuk létezik a sor, de az update már nem találja azt ott, vagy fordítva, azt látjuk nem létezik, de az insert idejére már bekerül, így constraint violation-t kapunk (ha a megkülönböztető oszlop egyedi).

if OBJECT_ID('dbo.Client') is not null drop table dbo.Client
go

create table dbo.Client
(
  id int not null primary key,
  name nvarchar(100)
)
go

--1. solution
if OBJECT_ID('dbo.UpsertClient1') is not null drop proc dbo.UpsertClient1
go

create proc dbo.UpsertClient1
  @id int,
  @name nvarchar(100)
as
set xact_abort on
begin transaction

if exists(select * from dbo.Client with (updlock, serializable) where id = @id)
  update dbo.Client set name = @name where id = @id
else
  insert dbo.Client (id, name) values (@id, @name)

commit
go

A serializable hint arra való, hogy a kulcsot (id) zárolja a szerver, így még akkor is védve van a kulcshoz tartozó sor, ha a sor nem is létezik, másrészt a tranzakció végéig fenntartja a select lockját.
Az updlock azért kell, mert ha két select egyszerre nekiszalad ugyanannak a sornak, mindkettő shared lock-kal lezárolva a sort, akkor a következő insert vagy update által igényelt exclusive lock nem adható ki, mert a másik shared-et tart rajta. Ez deadlock, mert mindkettő a másik miatt nem tud továbbmenni. Amúgy ezt conversation deadlocknak hívják, mert a lock felkonvertálás (shared -> exlcusive) miatt jön elő. Az alapprobléma ugye az, hogy a szerver kiad két shared lockot is a sorra (pontosabban kulcsra). A shared lockok kompatibilisek, azaz egyszerre akárhány folyamatnak kiadhatók, hisz mi értelme korlátozni a párhuzamos olvasó szálak számát?
Ebben az esetben azonban az olvasás után írás jön, ami deadlockot okoz. A megoldás, hogy az updlock hinttel nem shared, hanem update lockot kérünk a kulcsra. Két update lock ___NEM___ kompatibilis. Azaz, ha az első folyamat megszerezte az update lockot a kulcsra, a másik a tranzakció végéig (a serializable miatt) várni fog, hogy if exists-elhessen. Így az első update-el vagy insertál ahogy kijön neki, a második pedig az előző végeredménye alapján dönthet az if existsben.

Ez az első példa, lesz még 4 másik megközelítést alkalmazó, ezeket a következő napokban publikálom. Lássuk a sebesség tesztelést.
A kiinduló táblába 100e sort raktam, 100e és 200e közötti id-kkel. Ezt a táblát minden teszt előtt újraépítem.

truncate table dbo.Client
insert dbo.Client with(tablock) (id, name)
select top 100000 SalesOrderDetailID + 100000, rowguid 
from AdventureWorks.Sales.SalesOrderDetail order by SalesOrderDetailID

A tesztek eredményét egy táblába gyűjtöm:

if OBJECT_ID('MeasureResults') is null
    create table MeasureResults (procid int, duration int)

Maga a teszt:

set @d = sysdatetime()
declare @i1 int = 0
while (@i1 < 100000) begin declare @j1 int = rand() * 200000 exec UpsertClient1 @j1, 'apple' set @i1 += 1 end insert MeasureResults values(1, datediff(s, @d, sysdatetime())) [/source] A 100e upsert átlagban 40e beszúrást és 160e update-et eredményez. Azaz egy olyan mintának felel meg a tesztünk, amiben 80% update és 20% insert van. Hogy ez realisztikus-e az üzleti követelmények döntik el, nem lehet tudni előre, tesznek ez jó. A teszteket 10x ismételtem meg minden eljárásra. Az eredmények egyszerűen állanak elő: [source='sql'] select procid, AVG(duration) dur from MeasureResults group by procid [/source] Tempdb-n futtatva a következő eredményeket kaptam (mint említettem, a maradék 4 eljárást a napokban publikálom): [source='c'] procid dur ----------- ----------- 1 6 2 5 3 6 4 7 5 5 [/source] Sima user adatbázisban: [source='c'] procid dur ----------- ----------- 1 152 2 161 3 164 4 64 5 186 [/source] Mit tud a 4-es megoldás? Meglepő, mennyivel gyorsabb a tempdb, mi? Van valakinek ötlete, miért? Nekem egy van, a tempdb-ben a logírás aszinkron, szemben a sima db-kell. Tapasztalati úton azt láttam, hogy a tempdb esetén alig ír a vinyó, sima adatbázisnál meg majd megveszik. Esetleg más tipp?

Konferenciaanyagok

Thursday, May 8th, 2008

Tegnap lement a konferencia, én ahogy haladtunk előre egyre jobban feloldódtam és jobban éreztem magam. Egyből a délutáni előadással kellett volna kezdenem. :)

Ahogy már írtam korábban sok anyag készült, ami nem került bele a konf folyamába, ezeket hamarosan elkezdem kirakni ide.

Most első lépésként a két előadásom pptjét töltöttem fel.

Update: office 2003 ppt verzió

Bálint és a vegaság kritikája

Monday, May 5th, 2008

Bálint most kezdi felfogni, hogy nem eszek húst.
Ezzel kapcsolatban már volt pár megjegyzése, gyakorlatilag jókat röhög rajtam.

-Apa, te azért nem eszel húst, mert sajnálod a disznót?
-Igen.
-Én is sajnálom, de azért eszem.

-Apa, fáj a disznónak, ha lassan ölik?

-Tyúkos lepényt kérek.

-Egy sonkát lobogtatva az orrom előtt: Nézd, apa, ez itt egy malacpapa. :)

Magyarország szürkébb lenne a romák nélkül

Sunday, May 4th, 2008

Hirdeti az óriásplakát a 70-es út mellett (meg gondolom máshol is).

Orgonasípokat loptak Mezőkövesden

Igen, nagyon szürke lenne, sőt, kifejezetten unalmas. Ezek az áldott jó emberek, hogy az Isten áldja meg őket nap mint nap, ahol csak tudja. Annyi értéket teremtenek ennek az országnak! Hisz mekkora gradiensű lenne a lakosság fogyása, ha ők nem iparkodnának 2-3-szorosan túlteljesítve többségi polgártársaikat? Alig lenne lincselés, nem kellene a falukban félni az embereknek tőlük, az autók riasztópiaca nem menne úgy, bezárna sok MÉHtelep, nem maradna ki a telefon és az internet egy hétre egy komplett városrészben (nagyon érdekes a prezentáció róla), nem lennének balesetek az ellopott jelzőberendezések miatt, nem kellene félniük az orvosoknak a betegektől, nem kellene a mentősöknek önvédelmi tanfolyamra járniuk, nem lenne százér’ a (lopott) paprika, nem lenne cigi, cigi, cigi, nem kérdeznék meg az embereket olyan sűrűn a pontos időről, hogy aztán más síkra tereljék a beszélgetést, nem vernék annyit az iskolában a gyerekeket (és a tanárokat), nem kellene leszedni a gyümölcsöt zölden, mielőtt elmenne “magától” a kertből, nem kapnák meg a jól megérdelemt szexuális kielégítést az öregasszonyok, akár nekrofíliával párosítva, mér ne, hisz ha már lúd, legyen kövér, és a költségvetést se kellene annyira cipőkanállal összerakni a sok segílyke miatt. Nagyon rossz lenne, jaj de nagyon. (Aki szerint egyoldalú a lista, jöhet az a sok hozzádott értékkel, amivel a szürkeséget fűszerezik. Amivel hozzájárulnak, hogy kicsi legyen Mo. TCO-ja.) Még szerencse, hogy állami pénzen megnyugtatnak, így jó nekem. Mert hülye azért nem vagyok, ugye?

Elképesztő, komolyan. Kb. annyi értelme van ennek, mint amikor Kóka bemondta, hogy dübörög a gazdaság, nagy a jólét. Látja ezt sok ember, örül is neki. Ha Kóka mondja, akkor úgy van. Meg ha Feri, akkor is. Mindkettő hiteles ember, látjuk. Ha a cigányokkal jó élni a többieknek, és ezt felülről mondják, akkor az úgy van, pártunk ezt mondta, kuss legyen. Annak ellenére, hogy 9M ember ezt nem így éli meg. Nem baj, erőszakosan ránk kell erőltetni. Egészen addig, amíg robbanás nem lesz. Mert nekem az az érzésem, hogy nem kell erre sokat várni. Csak csinálják így tovább, hazudozva, felülről erőszakkal deszegregálva, az embereket hülyének nézve és kibaszva velük. Egy darabig működik. De aztán elszabadul a pokol. Nem kellene megvárni ezt a pillanatot. Vega vagyok, nem szeretem a vért. A cigányét se, meg a disznóét se.

Hazai SQL Server 2008 termékbejelentés – május 7

Sunday, May 4th, 2008

Az utóbbi két hétben azért nem volt bejegyzés az újdonságokról, mert minden éjszaka gőzerővel készültem a konferenciára.

Mint látható 2 teljes és egy fél előadásom lesz, eléggé fel kell kötnöm a gatyát. Nem annyira szakmailag, elég sokat foglalkoztam már a termékkel, hogy nagyon ne jöjjek zavarba vele kapcsolatban, hanem inkább az erőmet kell jól beosztanom.

A demókhoz elég sok példát összeraktam, amelyeket végül ki kellett dobni, mert nincs elég idő bemutatni őket, ezeket a konferencia után ki fogom rakni a blogba, ne vesszenek kárba.

Találkozunk szerdán.