SQL Server izolációs szintek
Sokan azt hiszik, ha beraknak néhány tsql utasÃtást egy tranzakciós blokkba, akkor máris védettek más kapcsolatok hatásaitól. Természetesen ez messzemenÅ‘kig nem igaz, a default read commmitted szint mellett simán szúrhatnak be vagy törölhetnek sorokat, miközben egy select dolgozik rajta, mivel a select mindig csak azon a kis tartományon tart locokot, amit éppen olvasgat. Azon a pár lapon pl.
Ez egész gondolatmenet innen indult. A szerzÅ‘ azt bizonygatja, tök jó a NOLOCK hint, mert Ãgy gyorsabb lesz a query. Persze, valamelyest biztos, hisz ilyenkor egyáltalán nem rak lockokat a szerver az olvasott sorokra. A hozzászólásokban persze jól odamondják a jóembernek, hogy ne beszélj ilyenekrÅ‘l, mert sok hozzá nem értÅ‘ ember azt hiszi, ez valami tuning lehetÅ‘ség, miközben súlyos adathibák léphetnek fel a read UNcommitted szinten, a NOLOCK miatt.Â
Ez egyik hozzászólásban volt egy érdekes gondolat:
“Anyway, there is a little catch with NOLOCK however. SQL Server mostly uses unordered clustered index scans when NOLOCK is specified, this can cause duplicate records to be returned when page splits occur while your query is scanning the index.”
Szóval nem feltétlen csak olyan sorok jöhetnek be, amiket esetleg egy másik tranzakció még visszavon, hanem még ugyanaz a sor is bejöhet duplikálva. Persze, aki ésszel használja, pl. statisztikai funkciókra, azt ez nem értekli, de fontos, hogy mindenki realizálja a NOLOCK veszélyeit.
A hozzászólásokban van egy link erre a cikkre, innen bedig erre. Mindkettő az izolációs szintek anomáliát boncolgatja, érdemes átfutni őket.
Mi a helyzet a 2005-ben, a snapshot read committed bekapcsolása után? Nos, ebben az esetben a read committed szintű izolációs szint esetén a select a párhuzamos módosÃtás elÅ‘tti eredményeket adja vissza, ami egy bár idÅ‘ben eltolt, de konzisztens állapotot állÃt elÅ‘. Ezt a szintet nyilván azért szeretjük, mert az Ãrók nem blokkolják az olvasókat és vica versa. Ugyanezért szokták bevetni 2000-ben a NOLOCKot, csak itt nincs meg viszont az inkonzisztens adatok veszélye. Ezért szeretjük ezt az újÃtást, és erre irigykedett minden sql server programozó az orákulumra 2005 elÅ‘tt.
De persze ennek is meg van az ára. Minden egyes, a select futása alatti módosÃtást bevezet a szerver a tempdb-be, Ãgy mikor odaér a select a módosÃtott adathoz, akkor átnyúlnak a tempdbbe, és onnak veszik el a sor módosÃtás elÅ‘tti állapotát. Ez azért eléggé erÅ‘forrásigényes lehet. Különösen érdekes lehet a helyzet, ha egy order by-os selectet kérünk le. Ha az order by pont a clustering key mentén működik, akkor normál esetben egyszerűen olvasni kell a szervernek az adatlapokat, sorban, ez piszok gyors. Mi van viszont ebben a helyzetben? Foglalmam sincs, ilyenkor hogyan hajtja végre a kérést. Ha valaki tudja, ne tartsa magában. Köszönöm.
March 11th, 2007 at 10:54 am
Szia!
Érdemes megnézni ezt http://www.wisdomforce.com/dweb/resources/docs/MSSQL2005_ORACLE10g_compare.pdf az irományt, többek között az SQL2K5 és az ORA közötti lockolási különbségeket is taglalja, mint pl.
“Oracle provides similar performance with block based row versioning on the same hardware and OS compared to MSSQL with no row versioning”
PLusz SQL2K5-ben default ki van kapcsolva a row versioning, mÃg ORA-ban ki sem lehet kapcsolni. Ez azért sztem jelent valamit :-)
Üdv, L.
March 11th, 2007 at 3:16 pm
Lies, Damn Lies and Benchmarks. :)
Annak idején azt hittem, hogy a @ táblák a memóriában tárolódnak, a #-osok meg a TempDB-ben. Ezért kihoztam, hogy a @-osak gyorsabbak. Nem akartam hazudni, de valahogy mégis csak az jött ki, a legnagyobb jószándékom és őszinte igyekezetem ellenére.
Szóval minden ilyen szám, ez gyorsabb, az gyorsabb ingoványos vizekre evez.
Ennek ellenére biztos vagyok benne, hogy az Ora izolációs kódja sokkal öregebb, ezért sokkal optimalizáltabb, mint az SQL 2005 tempdbs megoldása.
Ennek ellenére örülünk neki. :)