<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rollback &#187; database engine</title>
	<atom:link href="http://blog.rollback.hu/tag/database-engine/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rollback.hu</link>
	<description>SQL, üzemeltetés kicsiknek és nagyoknak.</description>
	<lastBuildDate>Thu, 17 Nov 2011 16:38:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A count() ára</title>
		<link>http://blog.rollback.hu/2011/09/a-count-ara/</link>
		<comments>http://blog.rollback.hu/2011/09/a-count-ara/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 22:21:49 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Magyar]]></category>
		<category><![CDATA[database engine]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[üzemeltetés]]></category>

		<guid isPermaLink="false">http://blog.rollback.hu/?p=347</guid>
		<description><![CDATA[A count() függvénnyel kapcsolatosan van pár dolog, ami itt ugrál a fejemben már egy ideje, most kiborítom őket.
Először is: van egy komoly vallási kérdés a témában, miszerint vajon a count(1) vagy a count(*) a jobb. Ezt mind Oracle, mind MSSQL platformon keményen nyomják emberek. Legyünk egyszerűek, nézzünk meg egy végrehajtási tervet, és lássuk a valót: [...]]]></description>
			<content:encoded><![CDATA[<p>A count() függvénnyel kapcsolatosan van pár dolog, ami itt ugrál a fejemben már egy ideje, most kiborítom őket.</p>
<p>Először is: van egy komoly vallási kérdés a témában, miszerint vajon a <strong>count(1) </strong>vagy a <strong>count(*) </strong>a jobb. Ezt mind Oracle, mind MSSQL platformon keményen nyomják emberek. Legyünk egyszerűek, nézzünk meg egy végrehajtási tervet, és lássuk a valót: pontosan ugyanazt csinálja a szerver mindkét esetben. Lelke mélyén ő tudja, hogy pontosan ugyanaz a kérdés. Na de honnan van a válasz? Mivel azt kérdezzük ilyenkor, hogy hány sor is van a táblában, ez egy index scan lesz. És mivel az SQL Server okos, ezért <em>a legkisebb lapszámú indexet </em>fogja felolvasni. Nézzétek meg sok indexet hordozó táblákon, hogy milyen lehetetlen indexet bök ki. Általában azokat, amiknek nagy a NULL aránya, mivel azok kicsik. Persze filtered indexre nem ugrik.</p>
<p>A másik egy személyes élmény. Azt vettem észre egy szép napon, hogy a szerverek nagyon sok időt töltenek azzal, hogy <strong>select count(*) from sysfiles</strong> vagy <strong>select count(*) from sysobjects </strong>lekérdezéseket futtatnak. Hamar rájöttem, hogy ez egy marék Java alkalmazás műve, melyek sok kicsi lekérdezést indítottak, melyek előtt a JDBC driver futtatott egy health check kverit, hogy tudja, hogy jó az adatbáziskapcsolat, amit a poolból vett ki. Történetesen a health check drágább volt, mint sokszor a lekérdezés maga. A masteren a resourcedb miatt még join is van az execution planben. Mi egyszerűen átálltunk az alulmúlhatatlan <strong>select 1</strong>-re, de ha valakinek van hasonló gondja, inkább azt ajánlom, hogy válasszon egy táblát, és abból kérje le az első sort. Nekem ez sajnos a sok kis adatbázis miatt nem menő, mert senki nem fog mindegyikben táblát keresni, de másnak bejöhet. Nálam ez hatszoros telejsítménykülönbséget jelentett: 0.003 vs 0.018 total subtree costok jelentek meg.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rollback.hu/2011/09/a-count-ara/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Denali I. &#8211; SEQUENCE vs IDENTITY</title>
		<link>http://blog.rollback.hu/2010/11/denali-i-sequence-vs-identity/</link>
		<comments>http://blog.rollback.hu/2010/11/denali-i-sequence-vs-identity/#comments</comments>
		<pubDate>Sun, 21 Nov 2010 14:48:08 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Magyar]]></category>
		<category><![CDATA[database engine]]></category>
		<category><![CDATA[Denali]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://blog.rollback.hu/?p=312</guid>
		<description><![CDATA[Az egyik újdonság a Denali-ban a szekvencia. Eddig ilyen volt Oracle-ben, PostgreSQL-ben, most már van MSSQL-ben is. Eddig MSSQL-ben volt IDENTITY, de az egy kicsit más. Az IDENTITY egy adott tábla sémájához kötött autoincrementes oszlop, megadott kezdőértékkel és növekedési értékkel. Értéket neki nem adunk, hanem ő magától kitölti, kivéve ha azt mondjuk, hogy SET IDENTITY_INSERT [...]]]></description>
			<content:encoded><![CDATA[<p>Az egyik újdonság a Denali-ban a szekvencia. Eddig ilyen volt Oracle-ben, PostgreSQL-ben, most már van MSSQL-ben is. Eddig MSSQL-ben volt IDENTITY, de az egy kicsit más. Az IDENTITY egy adott tábla sémájához kötött autoincrementes oszlop, megadott kezdőértékkel és növekedési értékkel. Értéket neki nem adunk, hanem ő magától kitölti, kivéve ha azt mondjuk, hogy SET IDENTITY_INSERT tabla ON. Az általunk utoljára felhasznált értéket a @@IDENTITY változó illetve SCOPE_IDENTITY() függvény megmondja, ha szeretnénk. Ez jó. Viszont olyan mértékben a sémához van kötve, hogy az identity tulajdonság nem változtatható. Nem lehet se rátenni egy meglévő oszlopra, se levenni róla. Ez igen fájdalmas tud lenni időnként, és én még nem tudtam feldolgozni, hogy ez miért ilyen béna.<br />
<span id="more-312"></span></p>
<p>Ezzel szemben a szekvencia csupán egy sorszámosztó automata, amiből mindig leszedjük a következő számot, amikor kell. Nézzünk meg egy kedves összehasonlító elemzést, melyben ugyanazt végigcsináljuk identity és sequence esetre:</p>
<pre class="brush: sql;">
CREATE TABLE ident (a SMALLINT IDENTITY(32600,100), b INT);
GO
INSERT INTO ident
OUTPUT inserted.*
VALUES(1)
GO 3
</pre>
<p>Itt ugye létrejön a tábla, az identity érték miatt már csak két sort lehet beleszúrni, ezért a második batch harmadik futásánál jön a hiba, és ez lesz a kimenet:</p>
<pre class="brush: plain;">
Beginning execution loop
a      b
------ -----------
32600  1
(1 row(s) affected)
a      b
------ -----------
32700  1
(1 row(s) affected)
a      b
------ -----------
Msg 8115, Level 16, State 1, Line 1
Arithmetic overflow error converting IDENTITY to data type smallint.
Arithmetic overflow occurred.
** An error was encountered during execution of batch. Continuing.
Batch execution completed 3 times.
</pre>
<p>És innen csak egy DBCC CHECKIDENT segítségével szabadulhatunk el. </p>
<p>A szekvenciás élet elég hasonló:</p>
<pre class="brush: sql;">
CREATE TABLE sequen (a SMALLINT, b INT)
GO
CREATE SEQUENCE mysec
as SMALLINT
START WITH 32600
INCREMENT BY 100;
GO
INSERT INTO sequen
OUTPUT inserted.*
VALUES(NEXT VALUE FOR mysec, 1)
GO 3
</pre>
<p>Látjuk, hogy a szekvenciából a NEXT VALUE FOR varázsszó szippantja ki a soron következő számot. Ha nekiállunk SELECT NEXT VALUE FOR szekvencia parancsokat kiadni, akkor kiválóan pörgetjük a számlálót. Amúgy ez a kimenet:</p>
<pre class="brush: plain;">
The sequence object 'mysec' cache size is greater than the number of available values; the cache size has been automatically set to accommodate the remaining sequence values.
Beginning execution loop
a      b
------ -----------
32600  1
(1 row(s) affected)
a      b
------ -----------
32700  1
(1 row(s) affected)
a      b
------ -----------
Msg 11728, Level 16, State 1, Line 1
The sequence object 'mysec' has reached its minimum or maximum value. Restart the sequence object to allow new values to be generated.
** An error was encountered during execution of batch. Continuing.
Batch execution completed 3 times.
</pre>
<p>A két különbségből az egyik nyilvánvalóan az, hogy más a hibaüzenet meg hibakód. A másik viszont mókás: <em>The sequence object &#8216;mysec&#8217; cache size is greater than the number of available values; the cache size has been automatically set to accommodate the remaining sequence values.</em> Ez mit is jelent? Hát azt, hogy a szekvenciának a következő N értékét cache-eli az engine, és így sokkal gyorsabban tudja kiszolgálni a kéréseket. Ez persze azzal jár, hogy ha természetellenes módon áll meg a szerver, akkor a cache-elt értékek elvesznek, és a következő nem-cache-elt számtól megy tovább az élet. Esetünkben mindössze két lehetséges következő érték volt, ezért dobott egy warningot, hogy nem tudta megtölteni a cache-t. A sebességvonzatról annyit, hogy a cache-elt szekvencia a leggyorsabb, követi az identity, a sor végén pedig a no cache-es szekvencia ballag &#8211; azt azért tegyük hozzá, hogy a különbség 10-20% az egyes szintek között, szóval nem itt fogunk performanciát tuningolni.</p>
<p>Nézzük meg, hogy mit lehet még csinálni a szekvenciával! Hát, van egy olyan opciója is, hogy CYCLE, ebben az esetben amikor eléri az utolsó értéket, akkor reseteli magát a definíció szerinti alapértékre, itt pl. az utolsó beszúrás megint 32600 lett volna. Ha esetleg valahova máshova szeretnénk ugrani, vagy csak nincs a CYCLE opció bekapcsolva, akkor a RESTART opció segít. Paraméterek nélkül pont mint a cycle, de mondhatjuk úgy is, hogy </p>
<pre class="brush: sql;">
ALTER SEQUENCE mysec RESTART WITH 2011;
</pre>
<p>és akkor 2011-től pörög tovább a számláló. A szekvenciának mindene megváltoztatható: kezdőérték, növekmény (ez ugye fix az identity esetén), cycle ,cache, plusz lehet neki minvalue meg maxvalue opciót is megadni, hogy pl csak 10000 és 99999 közötti számokat adjon ki, és tutifix, h ötjegyű értékeket kapok, ha pl. ilyen a vágyam.</p>
<p>Ha pedig valaki teljesen megvadul, és kell neki 100 szám egymás után, azt is lehet kérni, a <a href="http://msdn.microsoft.com/en-us/library/ff878352(v=SQL.110).aspx">sp_sequence_get_range </a>tárolt eljárással, ami output paraméterekben tol vissza mindent.</p>
<p>Összességében a szekvencia egy kiváló lehetőség az identity-től való megszabadulásra, bár tudnám értékelni azt is, ha nem lenne így a tábla szívébe vésve az identity-ség. Valószínűleg azonban ez kevésbé volt fájdalmas a termékfejlesztőknek. Szerintem az esetek 90%-ában syntax sugar, néha &#8211; pl. ott, ahol több, mint egy sorszám kéne egy sorba, amit az identity nem enged &#8211; igazi haszna is van neki. Viszont mindenki, aki Oracle-ről MSSQL-re migrált eddig, most azt gondolja: miért nem vártam mostanáig? :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rollback.hu/2010/11/denali-i-sequence-vs-identity/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Indexek, amiket a kutya sem használ</title>
		<link>http://blog.rollback.hu/2009/10/indexek-amiket-a-kutya-sem-hasznal/</link>
		<comments>http://blog.rollback.hu/2009/10/indexek-amiket-a-kutya-sem-hasznal/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 14:36:04 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Magyar]]></category>
		<category><![CDATA[database engine]]></category>
		<category><![CDATA[DMV]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[üzemeltetés]]></category>

		<guid isPermaLink="false">http://blog.rollback.hu/?p=117</guid>
		<description><![CDATA[(apró technikai malőr miatt a táblázat pillanatnyilag bebújik a sidebar mögé, bocs, legjobb embereink dolgoznak a hiba elhárításán)
Az egyik nagy jósága a SQL 2005+ szervernek, hogy megmutatja az indexek ki(nem)használtságát, illetve elmondja, hogy milyen jelenleg nemlétező index mekkora hasznot hozna. Ezeket természetesen DMV-ken keresztül teszi meg velünk. 
Az indexeink kihasználtságát a sys.dm_db_index_usage_stats DMV mutatja meg, [...]]]></description>
			<content:encoded><![CDATA[<p>(apró technikai malőr miatt a táblázat pillanatnyilag bebújik a sidebar mögé, bocs, legjobb embereink dolgoznak a hiba elhárításán)</p>
<p>Az egyik nagy jósága a SQL 2005+ szervernek, hogy megmutatja az indexek ki(nem)használtságát, illetve elmondja, hogy milyen jelenleg nemlétező index mekkora hasznot hozna. Ezeket természetesen DMV-ken keresztül teszi meg velünk. </p>
<p>Az indexeink kihasználtságát a sys.dm_db_index_usage_stats DMV mutatja meg, egy kis minta így néz ki belőle:</p>
<pre class="brush: sql;">
SELECT top 3 * FROM sys.dm_db_index_usage_stats
WHERE object_id &gt; 255
</pre>
<p>Az erősen irányított válasz pedig<br />
<table id="wp-table-reloaded-id-6-no-1" class="wp-table-reloaded wp-table-reloaded-id-6" cellspacing="1" cellpadding="1" border="1">
<thead>
	<tr class="odd row-1">
		<th class="column-1">database_id</th><th class="column-2">object_id</th><th class="column-3">index_id</th><th class="column-4">user_seeks</th><th class="column-5">user_scans</th><th class="column-6">user_lookups</th><th class="column-7">user_updates</th><th class="column-8">last_user_seek</th><th class="column-9">last_user_scan</th><th class="column-10">last_user_lookup</th><th class="column-11">last_user_update</th><th class="column-12">system_seeks</th><th class="column-13">system_scans</th><th class="column-14">system_lookups</th><th class="column-15">system_updates</th><th class="column-16">last_system_seek</th><th class="column-17">last_system_scan</th><th class="column-18">last_system_lookup</th><th class="column-19">last_system_update</th>
	</tr>
</thead>
<tbody>
	<tr class="even row-2">
		<td class="column-1">5</td><td class="column-2">709577566</td><td class="column-3">2</td><td class="column-4">3</td><td class="column-5">3456</td><td class="column-6">0</td><td class="column-7">2154356</td><td class="column-8">NULL</td><td class="column-9">2009.10.18 15:46</td><td class="column-10">NULL</td><td class="column-11">2009-10-18 16:00:37.097</td><td class="column-12">0</td><td class="column-13">34</td><td class="column-14">0</td><td class="column-15">0</td><td class="column-16">NULL</td><td class="column-17">2009-10-18 01:00:23.000</td><td class="column-18">NULL</td><td class="column-19">NULL</td>
	</tr>
	<tr class="odd row-3">
		<td class="column-1">5</td><td class="column-2">709577566</td><td class="column-3">1</td><td class="column-4">2154356</td><td class="column-5">0</td><td class="column-6">2154356</td><td class="column-7">2154356</td><td class="column-8">2009-10-18 16:00:37.097</td><td class="column-9">NULL</td><td class="column-10">2009-10-18 16:00:37.097</td><td class="column-11">2009-10-18 16:00:37.097</td><td class="column-12">0</td><td class="column-13">34</td><td class="column-14">0</td><td class="column-15">0</td><td class="column-16">NULL</td><td class="column-17">2009-10-18 01:00:23.000</td><td class="column-18">NULL</td><td class="column-19">NULL</td>
	</tr>
	<tr class="even row-4">
		<td class="column-1">5</td><td class="column-2">709577566</td><td class="column-3">3</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">2154356</td><td class="column-8">NULL</td><td class="column-9">NULL</td><td class="column-10">NULL</td><td class="column-11">2009-10-18 16:00:37.097</td><td class="column-12">0</td><td class="column-13">34</td><td class="column-14">0</td><td class="column-15">0</td><td class="column-16">NULL</td><td class="column-17">2009-10-18 01:00:23.000</td><td class="column-18">NULL</td><td class="column-19">NULL</td>
	</tr>
</tbody>
</table>
<br />
Ebből a következőket kell figyelnünk: a db-object-index id-k magukért beszélnek, abból tudjuk, hogy minek is nézzük az adatait. A user seek/scan/lookup és a hozzájuk tartozó last&#8230; oszlopok talán a legfontosabbak, ők mutatják meg a tényleges indexhasználatot. Az user_update oszlop érdekes, az index ugyanis akkor update-elődik, ha a tartalmazott adat változik. Ez az úgynevezett indexkarbantartás, ami kissé drága, ezért nem szeretjük a felesleges indexeket. Merő véletlenségből a fenti minta pont tartalmaz egy ilyen indexet, a 3-as számút (egy tábla három indexének az értékeit választottam ki). Látszik, hogy semmi másra nem használja a szerver az indexet, csak karbantartja, frissítgeti. Ez egy tipikus jó jelölt arra, hogy letörölje az ember fia egy vidám hétfő reggelen, ha elég nagy minta alapján még mindig nulla a három mező összege. Volt szerencsém találkozni olyan indexszel, amit 1.1 milliárdszor kellett update-elnie az engine-nek, és soha nem használta. Lehet azt mondani, hogy nem kér enni, de hát szemmel láthatóan ez nem igaz.</p>
<p>Éles szemű egyének észrevehetik, hogy azért a system_scan oszlop értéke egyáltalán nem nulla. Ez anna kköszönhető, hogy az indexstatisztikák frissítéséhez az SQL szerver scannel. Úgyhogy ezt nem kell feltétlenül figyelembe venni. </p>
<p>Mire jó még ez a használati statisztika? Láthatjuk, hogy user_lookup mindig csak az index_id = 1 indexeken történik, azaz a clustered indexen. Természetes, hiszen a bookmark/key lookup itt szokott történni. Lehet, hogy van rá ellenpélda, de azt most kihagynám. És most keressük meg a legnagyobb user_scan értékű indexeket és a hozzájuk tartozó clustered indexeket: ha nagyon magas a clustered indexen a user_lookup érték is és kicsi a scan, akkor találtunk egy jó ellenjelöltet clustered indexre.</p>
<p>És megint, csak egyetlen DMV a sokból, és milyen sok hasznos dolgot árul el&#8230; Hát nem csodálatos? (nem, a csodálatos az az, hogy három tesztgépre sikerült három különböző SQL verziót/editiont telepítenem, anélkül, hogy észrevettem volna addig, amíg el nem frakkolt a teszt&#8230;)</p>
<p>Visszatérve a címre:</p>
<pre class="brush: sql;">
select * from sys.dm_db_index_usage_stats
where object_id &gt; 255
and user_seeks + user_scans + user_lookups = 0
order by database_id, object_id
</pre>
<p>Ők azok az indexek, akiket a kutya sem használt &#8211; az SQL Server legutóbbi indulása óta. Ez a DMV ugyanis minden szerver restartkor kiürül és újrakezdi a feltöltését a szerver. Tehát ha tegnap óta fut a gép, ne használjuk nagytakarításra az outputot. Tanácsos elmenteni a kimenetet &#8211; én mindennap elmentem egy külön táblába, és ha nem indult újra előző nap óta a szerver, akkor az előző napit meeg kitörlöm. Így csak legfeljebb egy napi statisztikát veszíthetek, de megvan hónapokra visszamenőleg minden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rollback.hu/2009/10/indexek-amiket-a-kutya-sem-hasznal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL újdonságok a piacon</title>
		<link>http://blog.rollback.hu/2009/05/sql-ujdonsagok-a-piacon/</link>
		<comments>http://blog.rollback.hu/2009/05/sql-ujdonsagok-a-piacon/#comments</comments>
		<pubDate>Sun, 24 May 2009 11:00:23 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Magyar]]></category>
		<category><![CDATA[database engine]]></category>
		<category><![CDATA[más tolla]]></category>
		<category><![CDATA[patch]]></category>

		<guid isPermaLink="false">http://blog.rollback.hu/?p=90</guid>
		<description><![CDATA[Egyelőre még mindig nem jutottam el oda, hogy egy normális szakmai cikket írjak, mert a *** automatizált szerver menedzsmentet csinálom (kárpótlásul a végén majd néhányat felteszek a scriptekből :), és úgy látszik, hogy nem tudok beszélni/írni róla meg csinálni is.
Viszont van két csodás hír, amivel nem is olyan régen találkoztam: az egyik az, hogy van [...]]]></description>
			<content:encoded><![CDATA[<p>Egyelőre még mindig nem jutottam el oda, hogy egy normális szakmai cikket írjak, mert a *** automatizált szerver menedzsmentet csinálom (kárpótlásul a végén majd néhányat felteszek a scriptekből :), és úgy látszik, hogy nem tudok beszélni/írni róla meg csinálni is.</p>
<p>Viszont van két csodás hír, amivel nem is olyan régen találkoztam: az egyik az, hogy van új Books Online az SQL 2008-hoz (és csak ismételni tudom magam, használjátok mindig a legfrissebb BOL-t), ha minden igaz, az SP1 CU2 verzióhoz van update-elve, letölthető <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&#038;FamilyID=765433f7-0983-4d7a-b628-0a98145bcb97">innen</a>. </p>
<p>Az SQL 2008 SP1 CU2 pedig az a verzió, amiről már korábban írtam, hogy nagyon várom, mondjuk én főleg SQL 2005-höz. Ugyanis itt válik lehetővé &#8211; egy külön megadott trace flaggel &#8211; az SQL szerver memóriájának a fizikai memóriában tartása, a fantasztikus <strong>lock pages in memory</strong>. Az <a href="http://blogs.msdn.com/psssql/archive/2009/05/19/an-update-for-standard-sku-support-for-locked-pages.aspx">SQL Server Support Team blogjában</a> olvasható egy szép cikk erről. Az SQL 2005 SP3 CU4 elméletileg egy hónap múlva itt lesz, tekintve, hogy eddig tartották a határidőt, én nagyon optimista vagyok.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rollback.hu/2009/05/sql-ujdonsagok-a-piacon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mondatok, amiket nem akarsz mondani az interjún II.</title>
		<link>http://blog.rollback.hu/2009/02/mondatok-amiket-nem-akarsz-mondani-az-interjun-ii/</link>
		<comments>http://blog.rollback.hu/2009/02/mondatok-amiket-nem-akarsz-mondani-az-interjun-ii/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 23:56:40 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Magyar]]></category>
		<category><![CDATA[database engine]]></category>
		<category><![CDATA[mssql]]></category>

		<guid isPermaLink="false">http://blog.rollback.hu/?p=59</guid>
		<description><![CDATA[A memória, a diszk és a tranzakció
Ez minden alkalommal tanulságos (és hosszú) beszélgetésekhez vezetett. Van egy nyitott tranzakcióm, ami már csinált egy csomó módosítást. Hol tartja a megváltozott, illetve a régi adatot az SQL szerver, iletve mi szerepel a tranzakciós naplóban? Bónusz: mi van a diszkre kiírva, és mi van csupán a memóriában? A kérdés [...]]]></description>
			<content:encoded><![CDATA[<h3>A memória, a diszk és a tranzakció</h3>
<p>Ez minden alkalommal tanulságos (és hosszú) beszélgetésekhez vezetett. Van egy nyitott tranzakcióm, ami már csinált egy csomó módosítást. Hol tartja a megváltozott, illetve a régi adatot az SQL szerver, iletve mi szerepel a tranzakciós naplóban? Bónusz: mi van a diszkre kiírva, és mi van csupán a memóriában? A kérdés megválaszolása némi adatbázis ismerettel és nagy adag józan paraszti ésszel (vagy ezek más jellegű lineáris kombinációjával) megválaszolható.<br />
Induljunk az elejétől: hol lehet a megváltozott adat? Vagy a diszken vagy memóriában, vagy egyéb helyen. Nézzük a diszket: Vajon kiír-e az SQL minden egyes változást külön-külön diszkre? (Lehet-e okos az SQL szerver, és megvárhatja-e a módosítások végét? Nyilvánvalóan nem, hiszen ha olyanom van, öt napig futtatom a tranzakciómat.) Milyen érzést okozna ez abban, aki mondjuk másfélmillió rekordot módosít&#8230;? Mostanra eljutottunk oda, hogy nem ír ki diszkre mindent. Esetleg a memória? Hát, a temptáblákhoz hasonló ellenpélda itt is ül: végre lehet hajtani egy akkora tranzakciót, amelyik több adatot módosít, mint amennyit fejben (memóriában) tudna tartani az adatbáziskezelő. Marad az egyéb, és a kis adatbáziskezelői ismeret: a memóriában tartott módosult lapok esetében az SQL szervert olyan nagyon nem érdekli, hogy a módosító tranzakció kommitált lett-e vagy még fut. Ha a lap módosult (azaz dirty page lett belőle, nem egyezik meg a memóriában lévő másolat a diszken lévő másolattal), a checkpoint processz ki fogja írni a diszkre. Na ja, de mi van rollbacknél? Hát, egyrészt a tranzakciók elsöprő többsége committal zárul, tehát a hurráoptimizmusa az SQL szervernek elég indokolt a hatékonyság nézőpontjából. Amúgy pedig rollbacknél egyszerűen visszaírja a régi adatokat a lapokra, amik ettől megint dirty page-ek lesznek, és a következő checkpoint majd kiírja a diszkre megint.<br />
Egy kérdést megválaszoltunk, itt az új: honnan írja vissza az eredeti adatot rollbacknél a szerver? Hát a tranzakciós naplóból! (Kis gondolkozással, illetve egy áramszünet utáni konzisztens adatbázis elképzelésével rájövünk, hogy a logot leginkább diszkre írja az SQL szerver.) És mi kerül a logba? Az, ami a rollbackhez illetve az esetleges újra-végrehajtáshoz kell (képzeljük el, hogy a tranzakció commitálódott, de a módosult rekordok még dirty page-en voltak, amikor a szomszédos építkezésen elkaparták a villamos kábelt a földben – ezt kiválóan fel tudja dolgozni az SQL Server – meg minden civilizált RDBMS). (És most nagyvonalúan ignorálom a bulk műveletek naplózásának kérdését.) Tehát kell minden módosult rekordnak az azonosítója (a primary key megteszi, ha van) és a változott oszlopok régi és új értékei. Azaz a naplóba nem maguk az utasítások kerülnek rögzítésre, hanem a hatásuk.<br />
Mostanra már azt is tudjuk, hogy mikor mi van a diszken és a memóriában. Memóriában az az adat van, amit legutóbb használt az SQL, a diszken meg a többi. Nem volt ebben semmi különös, próbáltam kicsit illusztrálni, hogy hogyan lehet mély ismeretek nélkül mély ismereteket szerezni :) – vagy legalábbis megfejteni működési elveket: állítsunk fel modelleket, és teszteljük őket általános és szélsőséges esetekre. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rollback.hu/2009/02/mondatok-amiket-nem-akarsz-mondani-az-interjun-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

