<?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>Wayne Sheffield, Author at SQL Solutions Group</title>
	<atom:link href="https://sqlsolutionsgroup.com/author/waynesheffield/feed/" rel="self" type="application/rss+xml" />
	<link>https://sqlsolutionsgroup.com/author/waynesheffield/</link>
	<description></description>
	<lastBuildDate>Tue, 07 Jul 2026 23:05:10 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://sqlsolutionsgroup.com/wp-content/uploads/2021/01/cropped-SSG_FAVICON0002-32x32.png</url>
	<title>Wayne Sheffield, Author at SQL Solutions Group</title>
	<link>https://sqlsolutionsgroup.com/author/waynesheffield/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How TCP Chimney Offloading Affects SQL Server</title>
		<link>https://sqlsolutionsgroup.com/tcp-chimney-offloading/</link>
					<comments>https://sqlsolutionsgroup.com/tcp-chimney-offloading/#comments</comments>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Sat, 16 May 2020 14:34:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[TCP Chimney Offloading]]></category>
		<category><![CDATA[TCP/IP]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=1507</guid>

					<description><![CDATA[<p>TCP Chimney Offload transfers network traffic workload processing from the CPU to a network adapter that supports TCP Chimney Offload. This feature was introduced with Windows Server 2003 SP2, and it was called the Microsoft Scalable Networking Pack (SNP). Since Windows Server 2008, these features are a base part of these operating systems, so they [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/tcp-chimney-offloading/">How TCP Chimney Offloading Affects SQL Server</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>TCP Chimney Offload transfers network traffic workload processing from the CPU to a network adapter that supports TCP Chimney Offload. This feature was introduced with Windows Server 2003 SP2, and it was called the Microsoft Scalable Networking Pack (SNP). Since Windows Server 2008, these features are a base part of these operating systems, so they no longer go by this name. To utilize this feature, the network adapter (and driver) must support this feature, and both the operating system and the network adapter must have this setting enabled.</p>
<p>This feature is not suitable for all applications. Microsoft says (at <a href="https://technet.microsoft.com/en-us/library/gg162709%28v=WS.10%29.aspx">https://technet.microsoft.com/en-us/library/gg162709%28v=WS.10%29.aspx</a>):</p>
<blockquote><p>Because of the overhead associated with moving TCP/IP processing to the network adapter, TCP Chimney Offload offers the most benefit to applications that have long-lived connections and transfer large amounts of data. Servers that perform database replication, function as file servers, or perform backup functions are examples of computers that may benefit when you enable TCP Chimney Offload.</p></blockquote>
<p>With the different operating systems versions, this feature is by default in different states:</p>
<table style="height: 190px;" border="1" width="404">
<tbody>
<tr>
<td><strong>Windows OS</strong></td>
<td><strong>Default state of TCP Chimney Offload</strong></td>
</tr>
<tr>
<td>Windows Server 2003</td>
<td>enabled</td>
</tr>
<tr>
<td>Windows Server 2008</td>
<td>disabled</td>
</tr>
<tr>
<td>Windows Server 2008 R2</td>
<td>automatic</td>
</tr>
<tr>
<td>Windows Server 2012</td>
<td>disabled</td>
</tr>
</tbody>
</table>
<p>With all of these changes to the OS, which setting should we use for SQL Server? In general, for all of these operating systems, I recommend that TCP Chimney Offload be disabled – because you can see odd connectivity problems in any other state. Notice in the above quote that Microsoft says that this feature is best used for applications with long-lived connections that transfer large amounts of data &#8211; hopefully your OLTP database is performing lots of short-lived connections and they are not transferring large amounts of data (if they are, contact us&#8230; we can help you with that!). Some of the error messages that you can encounter are:</p>
<blockquote><p>[Microsoft][ODBC SQL Server Driver][DBNETLIB] General Network error. Check your network documentation</p></blockquote>
<blockquote><p>ERROR [08S01] [Microsoft][SQL Native Client]Communication link failure</p></blockquote>
<blockquote><p>System.Data.SqlClient.SqlException: A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 – An existing connection was forcibly closed by the remote host.)</p></blockquote>
<p>These errors are not exclusive to having problems with the TCP Chimney Offload. Additionally, they may only occur during times of high network load on the server.</p>
<hr />
<p class="has-text-align-center" style="font-size: 20px;">Do you keep upgrading hardware to improve</p>
<p class="has-text-align-center" style="font-size: 20px;">SQL Server performance issues without seeing any benefits?</p>
<p class="has-text-align-center" style="font-size: 20px;">You need a Health Check from SQL Solutions Group.</p>
<p class="has-text-align-center" style="font-size: 20px;"><a href="https://sqlsolutionsgroup.com/services/sql-health-check/" target="_blank" rel="noopener noreferrer"><span style="text-decoration: underline;">Learn More</span></a></p>
<hr />
<h3>To determine the Current TCP Chimney Offload Setting and to Disable it</h3>
<p>In typical Microsoft format, this also varies between different operating system versions.</p>
<p>For Windows Server 2003, you need to check the registry. From a DOS command prompt, run:</p>
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\<span class="kw1">PARAMETERS</span> <span class="sy0">/</span>v EnableTCPChimney</pre></div></div>
<p>If disabled, this will have a value of 0x0; if enabled, it will have a value of 0x1.</p>
<p>To disable, from an elevated DOS command prompt, run:</p>
<div id="crayon-5d72a25b0ea83425158377" class="crayon-syntax crayon-theme-ssms2012 crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-mouseover">
<div class="crayon-toolbar" data-settings=" show"><div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">netsh <span class="kw1">INT</span> ip <span class="kw1">SET</span> chimney DISABLED</pre></div></div></p>
</div>
</div>
<div data-settings=" show"></div>
<div data-settings=" show">From Windows Server 2008 on, you can check the setting with this DOS command:</div>
<div data-settings=" show"></div>
<div data-settings=" show"><div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">netsh <span class="kw1">INT</span> tcp show <span class="kw1">GLOBAL</span></pre></div></div></p>
</div>
<div data-settings=" show"></div>
<div data-settings=" show">To disable it run the following from an elevated DOS command prompt:</div>
<div data-settings=" show"></div>
<div data-settings=" show"><div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">netsh <span class="kw1">INT</span> tcp <span class="kw1">SET</span> <span class="kw1">GLOBAL</span> chimney<span class="sy0">=</span>disabled</pre></div></div></p>
</div>
<div data-settings=" show"></div>
<div data-settings=" show">
<h3>References:</h3>
<p><a href="https://support.microsoft.com/default.aspx?scid=kb;EN-US;942861">https://technet.microsoft.com/en-us/library/gg162709%28v=WS.10%29.aspx</a></p>
<p><a href="https://support.microsoft.com/default.aspx?scid=kb;EN-US;942861">https://support.microsoft.com/default.aspx?scid=kb;EN-US;942861</a></p>
<p><a href="https://technet.microsoft.com/en-us/library/gg162709%28v=WS.10%29.aspx">https://technet.microsoft.com/en-us/library/gg162709%28v=WS.10%29.aspx</a></p>
<p><a href="https://blogs.msdn.com/b/cindygross/archive/2009/10/22/sql-server-and-tcp-chimney.aspx">https://blogs.msdn.com/b/cindygross/archive/2009/10/22/sql-server-and-tcp-chimney.aspx</a></p>
<p><a href="https://blogs.msdn.microsoft.com/psssql/2008/10/01/tcp-chimney-offload-possible-performance-and-concurrency-impacts-to-sql-server-workloads/">https://blogs.msdn.microsoft.com/psssql/2008/10/01/tcp-chimney-offload-possible-performance-and-concurrency-impacts-to-sql-server-workloads/</a></p>
</div>
<div data-settings=" show"></div>
<p>The post <a href="https://sqlsolutionsgroup.com/tcp-chimney-offloading/">How TCP Chimney Offloading Affects SQL Server</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/tcp-chimney-offloading/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Combating SQL Injection</title>
		<link>https://sqlsolutionsgroup.com/combating-sql-injection/</link>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Wed, 16 Sep 2015 13:53:39 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[sql injection]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2590</guid>

					<description><![CDATA[<p>Target. Home Depot. NASA. U.S. Army. Anthem. Wall Street Journal. MarketWired. Ashley Madison. What do they all have in common? They are all recent victims of cyber-attacks – several of these are confirmed to involve SQL Injection. Even though the exact method used to penetrate the other systems has not been released, experts believe that [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/combating-sql-injection/">Combating SQL Injection</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2015/10/secret_i.png"><img decoding="async" class="alignright wp-image-2635 size-medium" src="https://sqlsolutionsgroup.com/wp-content/uploads/2015/10/secret_i-300x152.png" alt="SQL injection" width="300" height="152" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2015/10/secret_i-300x152.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2015/10/secret_i-768x390.png 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2015/10/secret_i.png 922w" sizes="(max-width: 300px) 100vw, 300px" /></a>Target. Home Depot. NASA. U.S. Army. Anthem. Wall Street Journal. MarketWired. Ashley Madison. What do they all have in common? They are all recent victims of cyber-attacks – several of these are confirmed to involve SQL Injection. Even though the exact method used to penetrate the other systems has not been released, experts believe that SQL Injection was involved in all of these cases. Take a look at <span style="text-decoration: underline;"><span style="color: #0000ff;"><a style="color: #0000ff; text-decoration: underline;" href="https://codecurmudgeon.com/wp/sql-injection-hall-of-shame/" target="_blank" rel="noopener noreferrer">https://codecurmudgeon.com/wp/sql-injection-hall-of-shame/</a></span></span> for places that are known victims of SQL Injection.</p>
<p>The part that is really astonishing is that we have known how to stop SQL Injection for more than a decade. Completely. Dead. In. Its. Tracks. Which means that the problems happening today are because of careless coding techniques, and as such, they can be prevented.</p>
<h3>The “Funky query”</h3>
<p>A few years ago, I was working for a company that developed and sold software. One day, my supervisor sends me an email titled “Funky query”. Hmm, that sounds interesting… I’ll open this up right away, instead of ignoring it until I finish what I’m currently working on (like I would usually do).</p>
<blockquote><p>Wayne… one of our customer support engineers sent us this from the application error log of a customer. They were running a report. Any ideas on how this funky query came to be?</p>
<p>Query from error log (genericized… because I can’t use the real query):</p>
<p>SELECT * FROM sys.objects WHERE name = &#8216;O&#8217;Malley&#8217;</p>
<p>Details from the error log:</p>
<pre><span style="color: #ff0000;">Incorrect syntax near 'Malley'.
Unclosed quotation mark after the character string ''.</span></pre>
</blockquote>
<p>Me: Umm, boss… Does this report allow users to enter search criteria?</p>
<p>Boss: But of course!</p>
<p>Me: Well, I really hate to tell you this, but we have a SQL Injection problem.</p>
<p>And after a bit of back and forth where the developers were insisting that no way was there a SQL Injection problem, I sat down with the dev team lead and the boss and proved it to them. We created a dummy table in the database, went to the report criteria form, and I dropped the table.</p>
<p>Wayne: +1000</p>
<p>Development Team: -1000</p>
<h3>Defining SQL Injection</h3>
<p>Before we go into how SQL injection occurs, let’s first examine what it is:  a code injection technique that allows SQL code that the user enters in the front-end to be run against the back-end database.</p>
<p>Please note a few things about this definition:</p>
<ol>
<li>SQL Server was not mentioned. <em>Any and all</em> database platforms are susceptible to SQL injection. SQL Server. Oracle. PostgreSQL. DB2. It doesn’t matter – all database platforms are susceptible.</li>
<li>A generic front-end is mentioned. This is anything that connects to a back-end database, be it a web form or your favorite application. Anything that connects to a database can allow it.</li>
<li>Improperly written code within the database (such as a stored procedure) can allow it. It’s all about how the query is created and run against the database.</li>
<li>There are other forms of injection attacks that can occur. Other forms include Cross-site scripting, Web Parameter Tampering, LDAP Injection and XPath Injection (as I write this, WordPress 4.3.1 is being released to fix two Cross-site scripting issues).</li>
</ol>
<p>SQL injection can happen in three different ways:</p>
<ol>
<li>Classic – this is when a user enters SQL code, and can immediately view the results on screen.</li>
<li>Blind – this is essentially a classic attack, but the user does not see the results. Things may still happen, and the user may be able to send results to files that can be downloaded, but the results are not shown on screen.</li>
<li>Second Order – the user-supplied SQL code is actually stored in the database, and at a later point in time it is run.</li>
</ol>
<h3>Creating SQL Injection</h3>
<p>SQL injection happens when a SQL statement is created from the data supplied by the user, and it is run by the application or other process. Obviously the intention of the application is to only run the queries that it supplies. Consider a login form with user name and password data entry fields. Assume that the user enters “Mike” as the user, and “1234” as the password. In this case, the application essentially performs:</p>
<div id="wpshdo_5" class="wp-synhighlighter-outer"><div id="wpshdt_5" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_5"></a><a id="wpshat_5" class="wp-synhighlighter-title" href="#codesyntax_5"  onClick="javascript:wpsh_toggleBlock(5)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_5" onClick="javascript:wpsh_code(5)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_5" onClick="javascript:wpsh_print(5)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_5" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DECLARE</span> @UserName <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'Mike'</span>;
<span class="kw1">DECLARE</span> @Password <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'1234'</span>
<span class="kw1">DECLARE</span> @SQLCMD <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="kw2">MAX</span><span class="br0">&#41;</span>;
<span class="kw1">SET</span> @SQLCMD <span class="sy0">=</span> <span class="st0">'SELECT UserName, Password
FROM dbo.Users
WHERE UserName = '</span><span class="st0">''</span> <span class="sy0">+</span> @UserName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AND Password = '</span><span class="st0">''</span> <span class="sy0">+</span> @Password <span class="sy0">+</span> <span class="st0">''</span><span class="st0">''</span>;
&nbsp;
<span class="kw1">EXECUTE</span> <span class="br0">&#40;</span>@SQLCMD<span class="br0">&#41;</span>;</pre></div></div>
<p>This will create the SQL statement:</p>
<div id="wpshdo_6" class="wp-synhighlighter-outer"><div id="wpshdt_6" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_6"></a><a id="wpshat_6" class="wp-synhighlighter-title" href="#codesyntax_6"  onClick="javascript:wpsh_toggleBlock(6)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_6" onClick="javascript:wpsh_code(6)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_6" onClick="javascript:wpsh_print(6)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_6" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">SELECT</span>        UserName, Password
<span class="kw1">FROM</span>          dbo.<span class="me1">Users</span>
<span class="kw1">WHERE</span>         UserName <span class="sy0">=</span> <span class="st0">'Mike'</span>
<span class="sy0">AND</span>           Password <span class="sy0">=</span> <span class="st0">'1234'</span></pre></div></div>
<p>And when we run this, we get the expected results. But now, a hacker becomes the user. Being wise to SQL injection, the hacker enters for the password the string</p>
<div class="crayon-toolbar" data-settings=" show">
<div id="wpshdo_7" class="wp-synhighlighter-outer"><div id="wpshdt_7" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_7"></a><a id="wpshat_7" class="wp-synhighlighter-title" href="#codesyntax_7"  onClick="javascript:wpsh_toggleBlock(7)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_7" onClick="javascript:wpsh_code(7)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_7" onClick="javascript:wpsh_print(7)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_7" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="nu0">1234</span><span class="st0">' OR 1=1;--</span></pre></div></div>
</div>
<div data-settings=" show"></div>
<div data-settings=" show">
<p>This results in the following SQL Statement being generated:</p>
<div id="crayon-5d7105bb49b7e165120873" class="crayon-syntax crayon-theme-ssms2012 crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-mouseover">
<div class="crayon-toolbar" data-settings=" show">
<div id="wpshdo_8" class="wp-synhighlighter-outer"><div id="wpshdt_8" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_8"></a><a id="wpshat_8" class="wp-synhighlighter-title" href="#codesyntax_8"  onClick="javascript:wpsh_toggleBlock(8)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_8" onClick="javascript:wpsh_code(8)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_8" onClick="javascript:wpsh_print(8)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_8" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">SELECT</span>        UserName, Password
<span class="kw1">FROM</span>          dbo.<span class="me1">Users</span>
<span class="kw1">WHERE</span>         UserName <span class="sy0">=</span> <span class="st0">'Mike'</span>
<span class="sy0">AND</span>           Password <span class="sy0">=</span> <span class="st0">'1234'</span> <span class="sy0">OR</span> 1<span class="sy0">=</span><span class="nu0">1</span>; <span class="co1">--</span></pre></div></div>
</div>
</div>
</div>
<div data-settings=" show"></div>
<div data-settings=" show">
<p>Since every row matches the “OR 1=1” predicate, every username and password will be returned.</p>
<p>Hacker: +1</p>
<p>Developer: -1</p>
<p>Notice that I showed this attack with T-SQL code – this means that you can have SQL injection vulnerabilities within your T-SQL code (such as stored procedures), as well as any SQL commands that the application might construct and send to the database. The application might be properly handling for SQL injection, but if it is calling SQL code that is improperly coded, you can still be vulnerable. Everything has to be done properly – all it takes is one point where injection is possible to become the latest victim.</p>
<h3>What can a hacker do with a vulnerability?</h3>
<p>At this point, the hacker knows that the application is susceptible to SQL injection, and can now issue any SQL statement desired. Depending on the access level that the application has to connect to the database, the hacker can:</p>
<ol>
<li>Get a list of all of the databases in the instance.</li>
<li>Get a list of all of the tables in the current database, or any other database.</li>
<li>Query the data in any of the other tables that can be seen.</li>
<li>Modify (insert / update / delete) data in any of the tables that can be seen.</li>
<li>Create / modify / drop any object in any database on the instance.</li>
<li>Create elevated permissions at the SQL Server instance level. This will allow the hacker to do anything they desire on this instance. Drop tables? Yes. Query any and all data? Yes.</li>
<li>Create elevated permissions at the Operating System level.</li>
<li>Install programs on the server.</li>
<li>Access any server on the network, and perform all of the above on those servers.</li>
</ol>
<p>Scary? Absolutely. However, as I mentioned before, we know how to prevent this. And it turns out that it’s not hard. Instead of making SQL Statements that include data (either as directly supplied from the user, or from the database), pass that data to the SQL statement through parameters.</p>
<p>If we take the previous example, and modify it to use parameters, we would have:</p>
<div id="wpshdo_9" class="wp-synhighlighter-outer"><div id="wpshdt_9" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_9"></a><a id="wpshat_9" class="wp-synhighlighter-title" href="#codesyntax_9"  onClick="javascript:wpsh_toggleBlock(9)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_9" onClick="javascript:wpsh_code(9)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_9" onClick="javascript:wpsh_print(9)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_9" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DECLARE</span> @UserName <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'Mike'</span>;
<span class="kw1">DECLARE</span> @Password <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'1234'</span><span class="st0">' OR 1=1;--'</span>
<span class="kw1">SELECT</span>  UserName, Password
<span class="kw1">FROM</span>    dbo.<span class="me1">Users</span>
<span class="kw1">WHERE</span>   UserName <span class="sy0">=</span> @UserName 
<span class="sy0">AND</span>     Password <span class="sy0">=</span> @Password;</pre></div></div>
<p>What are the chances that you have a password of “1234′ OR 1=1; –” in your system? Assuming that you don’t, this query will return zero rows. SQL injection has been prevented.</p>
<p>So now you want an example of the difference between classic and blind SQL injection? Well, I’m not going to show you an example… because this will normally come down to how the application handles the data being returned. In the “OR 1=1” example, if the application only shows the first record, then the hacker won’t see the results of the SQL injection (unless they notice that it’s showing the wrong data). Or the application may have been coded to expect only one row, and if more are returned then it won’t display any.</p>
<h3>Second Order SQL Injection</h3>
<p>But how about a second order injection? Let me explain that with an example. Imagine a form for entering new users. The development team has learned about injection on the forms, and they are now using parameters. When the hacker enters for the password:</p>
<p>1234′ OR 1=1;–</p>
<p>The generated SQL statement is:</p>
</div>
<div id="wpshdo_10" class="wp-synhighlighter-outer"><div id="wpshdt_10" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_10"></a><a id="wpshat_10" class="wp-synhighlighter-title" href="#codesyntax_10"  onClick="javascript:wpsh_toggleBlock(10)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_10" onClick="javascript:wpsh_code(10)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_10" onClick="javascript:wpsh_print(10)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_10" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DECLARE</span> @UserName <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'Sam'</span>;
<span class="kw1">DECLARE</span> @Password <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'1234'</span><span class="st0">' OR 1=1;--'</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">Users</span> <span class="br0">&#40;</span>UserName, Password<span class="br0">&#41;</span>
<span class="kw1">VALUES</span> <span class="br0">&#40;</span>@UserName, @Password<span class="br0">&#41;</span>;</pre></div></div>
<p>When the data is queried:</p>
<div id="wpshdo_11" class="wp-synhighlighter-outer"><div id="wpshdt_11" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_11"></a><a id="wpshat_11" class="wp-synhighlighter-title" href="#codesyntax_11"  onClick="javascript:wpsh_toggleBlock(11)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_11" onClick="javascript:wpsh_code(11)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_11" onClick="javascript:wpsh_print(11)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_11" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">SELECT</span>  UserName, Password
<span class="kw1">FROM</span>    dbo.<span class="me1">Users</span>
<span class="kw1">WHERE</span>   UserName <span class="sy0">=</span> <span class="st0">'Sam'</span>;</pre></div></div>
<p>We get the following results:</p>
<div id="wpshdo_12" class="wp-synhighlighter-outer"><div id="wpshdt_12" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_12"></a><a id="wpshat_12" class="wp-synhighlighter-title" href="#codesyntax_12"  onClick="javascript:wpsh_toggleBlock(12)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_12" onClick="javascript:wpsh_code(12)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_12" onClick="javascript:wpsh_print(12)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_12" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">UserName Password
<span class="co1">-------- ----------------</span>
Sam      <span class="nu0">1234</span><span class="st0">' OR 1=1;--'</span></pre></div></div>
<p>The data has been stored in the database, and we are now primed for a second order injection attack. Some other process comes along (for example, a month-end report), and it creates dynamic SQL by building the SQL statement from the data. And the second order SQL injection has just been released…</p>
<h3>What have we learned so far?</h3>
<ol>
<li>SQL Injection can happen to any database system.</li>
<li>SQL Injection can be within SQL code (stored procedures), or it can be in the statements passed to the database from the application.</li>
<li>Parameters will prevent the SQL code from being executed immediately, thereby preventing Classic and Blind SQL Injection attacks.</li>
<li>The SQL Injection attempt can still be stored in the database, priming yourself for a Second Order SQL Injection attack.</li>
</ol>
<h3>Preventing SQL Injection</h3>
<p>Whenever you are creating a SQL statement, it must never create the statement with data (either from the database, or from what the user may pass). Instead, all SQL statements must use parameters. Even the month-end report.</p>
<p>Within SQL Server, have your queries reference the parameters (ColumnName = @VariableName). If you must use dynamic SQL to build your statement, use sp_executesql – it allows for the building of SQL statements with parameters, and then defining and passing those parameters in as the procedure is called.</p>
<p>In your application, there are several component choices. Some directly execute SQL, and others can use parameters. You want to always use the components that use parameters, and you must use those parameters.</p>
<h3>Learning more</h3>
<p>The <a href="https://www.owasp.org/">Open Web Application Security Project</a> is a community-driven, non-profit organization where experts analyze web application security issues and then compile a list of what the biggest issues are. For the last several years, the category “Injection” has been the biggest issue, and this includes SQL Injection.</p>
<p>This isn’t all that they do. They also have educational resources to not only instruct you on how these issues manifest themselves, but what to do about them. I strongly encourage everyone to take this resource back to your company, and to start identifying and addressing security issues in your code.</p>
<p>Another issue is that developers don’t really know about SQL Injection. In the workshops that I have given where this topic is presented, very few attendees have seen SQL Injection in a test environment. Most can barely give an adequate description of what it is. Those that have seen it are usually those who have been a victim of it. So I also recommend getting your company to arrange for SQL Injection training for the developers and DBAs. It would be good to send your QA team to this also.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/combating-sql-injection/">Combating SQL Injection</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automating DBCC DBTABLE &#8211; Obtaining the Disk Sector Size</title>
		<link>https://sqlsolutionsgroup.com/obtaining-the-disk-sector-size/</link>
					<comments>https://sqlsolutionsgroup.com/obtaining-the-disk-sector-size/#comments</comments>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Tue, 28 Apr 2015 06:49:27 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[DBCC]]></category>
		<category><![CDATA[disk sector]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=1975</guid>

					<description><![CDATA[<p>It’s a best practice to have the disk sector size (also known as the allocation unit size or block size) set to 64kb (see this white paper), so how can you get that info programmatically? I was recently reading this msdn article on Ghost Records, and it mentioned that you could get the number of [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/obtaining-the-disk-sector-size/">Automating DBCC DBTABLE &#8211; Obtaining the Disk Sector Size</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>It’s a best practice to have the disk sector size (also known as the allocation unit size or block size) set to 64kb (see <a href="https://msdn.microsoft.com/en-us/library/dd758814%28v=sql.100%29.aspx">this white paper</a>), so how can you get that info programmatically?</p>
<p>I was recently reading <a href="https://blogs.msdn.com/b/sqljourney/archive/2012/07/28/an-in-depth-look-at-ghost-records-in-sql-server.aspx">this msdn article</a> on Ghost Records, and it mentioned that you could get the number of ghost records on a page with DBCC DBTABLE… and it also mentioned that you need to be sure that you enable Trace Flag 3604 in order to see the results. So, two things immediately jumped out at me. First, I wanted to look at this to see where the ghost records were located. Secondly, I’ve just written a few articles (<a href="https://bit.ly/1x0awIS">here</a>, <a href="https://bit.ly/1E7UhP4">here</a>, <a href="https://bit.ly/1E7VBkY">here</a> and <a href="https://bit.ly/1xfm77y">here</a>) where I’ve been able to use the “WITH TABLERESULTS” option on the DBCC command to avoid using this trace flag and to provide automation for the process, and I wanted to see if that would work here also.</p>
<p>The good news is that “WITH TABLERESULTS” does indeed work with DBCC DBTABLE. The bad news is that I could not find the ghost record count in the results.</p>
<p>When I was looking for this information, I noted that the results meta-data are identical to the way DBCC PAGE has its output, so this means that the automation processes already developed will work for them. And as I was looking through the results, looking for a ghost record counter, I noticed two interesting fields:</p>
<table border="1">
<tbody>
<tr>
<td>m_FormattedSectorSize</td>
<td style="text-align: right;">4096</td>
</tr>
<tr>
<td>m_ActualSectorSize</td>
<td style="text-align: right;">512</td>
</tr>
</tbody>
</table>
<p>Hmm, this is showing me the disk Sector Size of each database file. After checking things on a few different systems, it looks like the m_ActualSectorSize is what the sector size is for the disk that the database file is currently on, and the m_FormattedSectorSize appears to be the sector size for when the database was created &#8211; and it is copied from the model database, so it appears to be what the disk was like when Microsoft created the model database.</p>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2015/04/disc.jpg"><img fetchpriority="high" decoding="async" class="size-large wp-image-4305 aligncenter" src="https://sqlsolutionsgroup.com/wp-content/uploads/2015/04/disc-1024x768.jpg" alt="disc sector size" width="669" height="502" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2015/04/disc-1024x768.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2015/04/disc-300x225.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2015/04/disc-768x576.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2015/04/disc.jpg 1200w" sizes="(max-width: 669px) 100vw, 669px" /></a></p>
<p>&nbsp;</p>
<p>Here&#8217;s where I answer my question from the first paragraph. After digging through the Object and ParentObject columns, I developed this script to get the current allocation using size (Sector Size) for each drive:</p>
<div id="wpshdo_13" class="wp-synhighlighter-outer"><div id="wpshdt_13" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_13"></a><a id="wpshat_13" class="wp-synhighlighter-title" href="#codesyntax_13"  onClick="javascript:wpsh_toggleBlock(13)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_13" onClick="javascript:wpsh_code(13)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_13" onClick="javascript:wpsh_print(13)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_13" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">USE</span> master;
GO
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'tempdb.dbo.#DBTABLE'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> <span class="kw1">DROP</span> <span class="kw1">TABLE</span> #DBTABLE
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> #DBTABLE <span class="br0">&#40;</span>
    ParentObject <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
    <span class="kw1">OBJECT</span>       <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
    Field        <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
    <span class="kw1">VALUE</span>        <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> #DBTABLE
<span class="kw1">EXECUTE</span> <span class="br0">&#40;</span><span class="st0">'DBCC DBTABLE WITH TABLERESULTS'</span><span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">WITH</span> cte1 <span class="kw1">AS</span>
<span class="br0">&#40;</span>
<span class="co1">-- get the objects for the dbt_dbid. Distinct to return only one per database</span>
<span class="kw1">SELECT</span>  <span class="kw1">DISTINCT</span> <span class="kw1">OBJECT</span>
<span class="kw1">FROM</span>    #DBTABLE
<span class="kw1">WHERE</span>   Field <span class="sy0">=</span> <span class="st0">'dbt_dbid'</span>
<span class="br0">&#41;</span>, cte2 <span class="kw1">AS</span>
<span class="br0">&#40;</span>
<span class="co1">-- get the objects related to the dbt_dbid for the m_Startup% field</span>
<span class="co1">-- SQL 2005/2008/2008R2 - looking for m_StartupState</span>
<span class="co1">-- SQL 2012+ - Looking for m_StartupPhase</span>
<span class="co1">-- So use m_Startup%</span>
<span class="kw1">SELECT</span>  <span class="kw1">DISTINCT</span> t1.<span class="kw1">OBJECT</span>
<span class="kw1">FROM</span>    #DBTABLE t1
<span class="sy0">JOIN</span>    cte1 <span class="kw1">ON</span> cte1.<span class="kw1">OBJECT</span> <span class="sy0">=</span> t1.<span class="me1">ParentObject</span>
<span class="kw1">WHERE</span>   t1.<span class="me1">Field</span> <span class="sy0">LIKE</span> <span class="st0">'m_Startup%'</span>
<span class="br0">&#41;</span>, cte3 <span class="kw1">AS</span>
<span class="br0">&#40;</span>
<span class="co1">-- get the filepath and sector size for each file</span>
<span class="kw1">SELECT</span>  fcb_filepath <span class="sy0">=</span> <span class="kw2">MAX</span><span class="br0">&#40;</span><span class="kw1">CASE</span> <span class="kw1">WHEN</span> Field <span class="sy0">=</span> <span class="st0">'fcb_filepath'</span> <span class="kw1">THEN</span> <span class="kw1">VALUE</span> <span class="kw1">ELSE</span> <span class="sy0">NULL</span> <span class="kw1">END</span><span class="br0">&#41;</span>,
        m_ActualSectorSize <span class="sy0">=</span> <span class="kw2">MAX</span><span class="br0">&#40;</span><span class="kw1">CASE</span> <span class="kw1">WHEN</span> Field <span class="sy0">=</span> <span class="st0">'m_ActualSectorSize'</span> <span class="kw1">THEN</span> <span class="kw1">VALUE</span> <span class="kw1">ELSE</span> <span class="sy0">NULL</span> <span class="kw1">END</span><span class="br0">&#41;</span>
<span class="kw1">FROM</span>    #DBTABLE t1
<span class="sy0">JOIN</span>    cte2 <span class="kw1">ON</span> cte2.<span class="kw1">OBJECT</span> <span class="sy0">=</span> t1.<span class="me1">ParentObject</span>
<span class="kw1">WHERE</span>   t1.<span class="me1">Field</span> <span class="sy0">IN</span> <span class="br0">&#40;</span><span class="st0">'fcb_filepath'</span>, <span class="st0">'m_ActualSectorSize'</span><span class="br0">&#41;</span>
<span class="kw1">GROUP</span> <span class="kw1">BY</span> cte2.<span class="kw1">OBJECT</span>, t1.<span class="kw1">OBJECT</span>
<span class="br0">&#41;</span>
<span class="co1">-- and now get the distinct list of drives and their sector sizes</span>
<span class="kw1">SELECT</span>  <span class="kw1">DISTINCT</span> Drive,
        m_ActualSectorSize,
        is_64kb <span class="sy0">=</span> <span class="kw1">CASE</span> <span class="kw1">WHEN</span> m_ActualSectorSize <span class="sy0">%</span> 65535 <span class="sy0">=</span> 0 <span class="kw1">THEN</span> 1 <span class="kw1">ELSE</span> 0 <span class="kw1">END</span>
<span class="kw1">FROM</span>    cte3
<span class="sy0">CROSS</span> APPLY <span class="br0">&#40;</span><span class="kw1">SELECT</span> Drive <span class="sy0">=</span> <span class="kw2">UPPER</span><span class="br0">&#40;</span><span class="kw1">LEFT</span><span class="br0">&#40;</span>fcb_filepath, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> ca
<span class="kw1">ORDER</span> <span class="kw1">BY</span> Drive;</pre></div></div>
<p>And here we have yet another way for how a process can be automated by using “WITH TABLERESULTS” on a DBCC command. I think that this one is a particularly good one to show the possibilities – to get this information you have to hit multiple parts of the DBCC results, and repeat it for each file in each database. Doing this by using the 3604 trace flag, finding the appropriate piece and then proceeding on to the piece would be very time consuming to do manually.</p>
<p>Finally, a quick note here: there are better ways of getting the disk sector size – since you can get it with WMI calls, you can get it with PowerShell (or even dos), and there are also command line utilities that will also get you this information. This is just a way to do it from within SQL Server. Note also that this only gets the drives that contain database files on this SQL Server instance – if you are looking for other drives, then this won’t work for you.</p>
<p>Take a look at the other fields that are available in DBTABLE – you just might find another item that you’d like to be able to retrieve.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/obtaining-the-disk-sector-size/">Automating DBCC DBTABLE &#8211; Obtaining the Disk Sector Size</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/obtaining-the-disk-sector-size/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Automating DBCC PAGE – Part 3: Is a Clustered Index physically sorted on disk?</title>
		<link>https://sqlsolutionsgroup.com/dbcc-page/</link>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Wed, 25 Mar 2015 06:11:58 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[DBCC page]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=1935</guid>

					<description><![CDATA[<p>In my last few blog posts, I’ve shared several methods of getting internal information from a database by using the DBCC PAGE command and utilizing the “WITH TABLERESULTS” option to be allowed to automate this process for further processing. This post will also do this, but in this case, we’ll be using it to bust [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/dbcc-page/">Automating DBCC PAGE – Part 3: Is a Clustered Index physically sorted on disk?</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In my <span style="text-decoration: underline;"><a href="https://sqlsolutionsgroup.com/automating-dbcc-page-part-2/">last few blog posts</a></span>, I’ve shared several methods of getting internal information from a database by using the DBCC PAGE command and utilizing the “WITH TABLERESULTS” option to be allowed to automate this process for further processing.</p>
<p>This post will also do this, but in this case, we’ll be using it to bust a common myth—data in a clustered index is physically stored on disk in the order of the clustered index.</p>
<p>To bust this myth, we’ll create a database, put a table with a clustered index into this database, and then we’ll add some rows in random order. Next, we will show that the rows are stored on the pages in logical order, and then we’ll take a deeper look at the page internals to see that the rows are not stored in physical order.</p>
<p>To start off with, let’s create a database and a table, and add a few rows to this table:</p>
<div id="wpshdo_14" class="wp-synhighlighter-outer"><div id="wpshdt_14" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_14"></a><a id="wpshat_14" class="wp-synhighlighter-title" href="#codesyntax_14"  onClick="javascript:wpsh_toggleBlock(14)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_14" onClick="javascript:wpsh_code(14)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_14" onClick="javascript:wpsh_print(14)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_14" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">IF</span> <span class="kw2">DB_ID</span><span class="br0">&#40;</span><span class="st0">'CIPageTest'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NULL</span>
<span class="kw1">CREATE</span> <span class="kw1">DATABASE</span> CIPageTest;
GO
<span class="co1">-- use the database</span>
<span class="kw1">USE</span> CIPageTest;
GO
<span class="co1">-- if the PageTest table exists, then drop it to start all over</span>
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'dbo.PageTest'</span>,<span class="st0">'U'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> <span class="kw1">DROP</span> <span class="kw1">TABLE</span> dbo.<span class="me1">PageTest</span>;
GO
<span class="co1">-- create the dbo.PageTest table</span>
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> dbo.<span class="me1">PageTest</span> <span class="br0">&#40;</span>
RowID <span class="kw1">INTEGER</span> <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="kw1">CLUSTERED</span>,
Col1 <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>1000<span class="br0">&#41;</span>
<span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">PageTest</span> <span class="br0">&#40;</span>RowID, Col1<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span>1, <span class="kw2">REPLICATE</span><span class="br0">&#40;</span><span class="st0">'Row01'</span>, 100<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">PageTest</span> <span class="br0">&#40;</span>RowID, Col1<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span>3, <span class="kw2">REPLICATE</span><span class="br0">&#40;</span><span class="st0">'Row03'</span>, 100<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">PageTest</span> <span class="br0">&#40;</span>RowID, Col1<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span>5, <span class="kw2">REPLICATE</span><span class="br0">&#40;</span><span class="st0">'Row05'</span>, 100<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">PageTest</span> <span class="br0">&#40;</span>RowID, Col1<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span>2, <span class="kw2">REPLICATE</span><span class="br0">&#40;</span><span class="st0">'Row02'</span>, 100<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">PageTest</span> <span class="br0">&#40;</span>RowID, Col1<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span>4, <span class="kw2">REPLICATE</span><span class="br0">&#40;</span><span class="st0">'Row04'</span>, 100<span class="br0">&#41;</span><span class="br0">&#41;</span>;</pre></div></div>
<p>What we have is a table with 5 rows. The table’s clustered key is the RowID integer column. The rows are inserted so that the odd rows are inserted first, followed by the even rows.</p>
<h4>Determine row’s physical location</h4>
<p>At this point, let’s look at where the system reports these rows to be at. To do this, we’ll utilize two undocumented system commands. The first is %%physloc%%, which returns the physical location in a hexadecimal format. The second is fn_PhysLocFormatter, which converts this into a format of FileID:PageID:SlotID. This is just simply added to the select clause, so the query is:</p>
<div id="wpshdo_15" class="wp-synhighlighter-outer"><div id="wpshdt_15" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_15"></a><a id="wpshat_15" class="wp-synhighlighter-title" href="#codesyntax_15"  onClick="javascript:wpsh_toggleBlock(15)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_15" onClick="javascript:wpsh_code(15)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_15" onClick="javascript:wpsh_print(15)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_15" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">SELECT</span>  RowID, 
        Col1, 
        sys.<span class="me1">fn_PhysLocFormatter</span><span class="br0">&#40;</span><span class="sy0">%%</span>physloc<span class="sy0">%%</span><span class="br0">&#41;</span> <span class="kw1">AS</span> <span class="br0">[</span><span class="kw1">FILE</span>:Page:Slot<span class="br0">]</span>
<span class="kw1">FROM</span>    dbo.<span class="me1">PageTest</span>;</pre></div></div>
<p>This query produces these results:</p>
<p><img decoding="async" src="https://blog.waynesheffield.com/wayne/wp-content/uploads/2016/10/DBCCPage3-1.png" alt="DBCCPage3-1" /></p>
<p>From these results, you can see that the rows are all on the same page, and that the slot in the slot array on that page are incrementing for the appropriate RowID value. Remember also that the slot array is zero-based, where the first slot is slot #0. This is the logical order.</p>
<h4>How inserts change the slot the row is in</h4>
<p>To see this changing around as the rows are inserted, just put the select statement (which I just introduced) after each of the prior insert commands and run the script to create the table and add the rows again. You will initially see RowID=1 put into Slot #0, RowID =3 into Slot #1 and RowID=5 into slot #2. When you then add RowID=2, this needs to be between RowID #s 1 and 3, so #2 is now in slot array #1, #3 moves to slot array #2, and #5 is moved to slot array #3. When you add RowID=4, it gets inserted into slot #3 and RowID#5 is again pushed down, to slot #4. The logical order follows what we are expecting:</p>
<p><img decoding="async" src="https://blog.waynesheffield.com/wayne/wp-content/uploads/2016/10/DBCCPage3-3.png" alt="DBCCPage3-3" /></p>
<h4>Check the physical storage</h4>
<p>In order to show that these are not physically stored in this order, we will need to crack this page and look internally at where the data is <em>actually</em> stored. We will accomplish this with this code:</p>
<div id="wpshdo_16" class="wp-synhighlighter-outer"><div id="wpshdt_16" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_16"></a><a id="wpshat_16" class="wp-synhighlighter-title" href="#codesyntax_16"  onClick="javascript:wpsh_toggleBlock(16)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_16" onClick="javascript:wpsh_code(16)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_16" onClick="javascript:wpsh_print(16)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_16" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DECLARE</span> @Page   <span class="kw1">INTEGER</span>,
       @SQLCMD <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="kw2">MAX</span><span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">DECLARE</span> @DBCC<span class="sy0">IN</span>D <span class="kw1">TABLE</span> <span class="br0">&#40;</span>
   PageFID         <span class="kw1">INTEGER</span>,   
   PagePID        <span class="kw1">INTEGER</span>,
   IAMFID         <span class="kw1">INTEGER</span>,
   IAMPID         <span class="kw1">INTEGER</span>,
   ObjectID       <span class="kw1">INTEGER</span>,
   IndexID        <span class="kw1">INTEGER</span>,
   PartitionNumber <span class="kw1">INTEGER</span>,
   PartitionID    <span class="kw1">BIGINT</span>,
   iam_chain_type  <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>100<span class="br0">&#41;</span>,
   PageType       <span class="kw1">INTEGER</span>,
   IndexLevel     <span class="kw1">INTEGER</span>,
   NextPageFID    <span class="kw1">INTEGER</span>,
   NextPagePID    <span class="kw1">INTEGER</span>,
   PrevPageFID    <span class="kw1">INTEGER</span>,
   PrevPagePID     <span class="kw1">INTEGER</span>
<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> @DBCC<span class="sy0">IN</span>D 
  <span class="kw1">EXECUTE</span> <span class="br0">&#40;</span><span class="st0">'DBCC IND (CIPageTest, '</span><span class="st0">'dbo.PageTest'</span><span class="st0">', -1)'</span><span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">SELECT</span> @Page <span class="sy0">=</span> PagePID
<span class="kw1">FROM</span>   @DBCC<span class="sy0">IN</span>D
<span class="kw1">WHERE</span>   PageType <span class="sy0">=</span> <span class="nu0">1</span>;
&nbsp;
<span class="kw1">SET</span> @SQLCMD <span class="sy0">=</span> <span class="st0">'DBCC PAGE (CIPageTest, 1, '</span> <span class="sy0">+</span> 
              <span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">15</span><span class="br0">&#41;</span>, @Page<span class="br0">&#41;</span> <span class="sy0">+</span> 
              <span class="st0">', 3) WITH TABLERESULTS'</span>;
&nbsp;
<span class="kw1">DECLARE</span> @DBCCPAGE <span class="kw1">TABLE</span> <span class="br0">&#40;</span>
   RowID           <span class="kw1">INTEGER</span> <span class="kw1">IDENTITY</span>,
   ParentObject    <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
   <span class="kw1">OBJECT</span>          <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
   Field           <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
   <span class="kw1">VALUE</span>           <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> @DBCCPAGE <span class="kw1">EXECUTE</span> <span class="br0">&#40;</span>@SQLCMD<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">SELECT</span> <span class="kw1">DISTINCT</span> Page <span class="sy0">=</span> @Page, ParentObject
<span class="kw1">FROM</span>   @DBCCPAGE
<span class="kw1">WHERE</span>   ParentObject <span class="sy0">LIKE</span> <span class="st0">'Slot%Offset%'</span>;</pre></div></div>
<p>Which produces these results:</p>
<p><img decoding="async" class="alignnone" src="https://blog.waynesheffield.com/wayne/wp-content/uploads/2016/10/DBCCPage3-2..png" alt="DBCC Page " width="339" height="156" /></p>
<h4>The row’s offset is where the row starts at on the page</h4>
<p>As we look at these results, pay close attention to the Offset. This is where the row physically starts on the page. You can see how for RowID #2, that this offset is higher than the offset for RowID #3… and even RowID #5. When the row was added, the data was added to the end of the other existing rows on the page, and the offset where this data starts was entered into the slot array, after having the remaining slot array entries pushed down in order to maintain the correct logical order. We can see this happening once again when RowID #4 is inserted.</p>
<p>And, finally, let’s use DBCC PAGE to crack open this page and look at the raw data. For this, we want to use dump style 2:</p>
<div id="wpshdo_17" class="wp-synhighlighter-outer"><div id="wpshdt_17" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_17"></a><a id="wpshat_17" class="wp-synhighlighter-title" href="#codesyntax_17"  onClick="javascript:wpsh_toggleBlock(17)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_17" onClick="javascript:wpsh_code(17)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_17" onClick="javascript:wpsh_print(17)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_17" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DECLARE</span> @Page <span class="kw1">INTEGER</span>;
<span class="kw1">SET</span> @Page <span class="sy0">=</span> xyz; <span class="co1">--&amp;lt;&amp;lt; set to the appropriate page from above</span>
<span class="kw1">DBCC</span> PAGE <span class="br0">&#40;</span>CIPageTest, 1, @Page, 2<span class="br0">&#41;</span> <span class="kw1">WITH</span> TABLERESULTS;</pre></div></div>
<p>If you expand out the VALUE column, you can see it go from Row01 to Row03 to Row05, then to Row02 and Row04.</p>
<p>So there you go… the data is physically stored in the next available space on the page;<strong> however</strong>, the page’s slot array is in the clustered key order. Furthermore, we now know that we can look at the offset and determine the order on the page. And we also have yet another way to use DBCC PAGE in an automated manner to show this.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/dbcc-page/">Automating DBCC PAGE – Part 3: Is a Clustered Index physically sorted on disk?</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automating DBCC Page</title>
		<link>https://sqlsolutionsgroup.com/automating-dbcc-page/</link>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Tue, 23 Dec 2014 22:31:20 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=1914</guid>

					<description><![CDATA[<p>Way back in 2006, Paul Randal documented DBCC PAGE on his Microsoft blog at https://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/06/10/625659.aspx. In his post, you will notice that in order to return the output from DBCC PAGE to the screen, you need to enable trace flag 3604 first. The above blog post shows a few examples of the results and utilizing [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/automating-dbcc-page/">Automating DBCC Page</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Way back in 2006, Paul Randal documented DBCC PAGE on his Microsoft blog at <a href="https://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/06/10/625659.aspx">https://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/06/10/625659.aspx</a>. In his post, you will notice that in order to return the output from DBCC PAGE to the screen, you need to enable trace flag 3604 first. The above blog post shows a few examples of the results and utilizing them for further actions. Unfortunately, this method requires manual intervention to get the necessary data from the page in order to work with it further.</p>
<p>You know, it sure would be nice if the manual intervention could be removed and to completely automate the task that you are looking for. This blog post is going to show you how this can be done, and it will give a few examples of doing so.</p>
<p>In <a title="Read now" href="https://bit.ly/1x0awIS" target="_blank" rel="noopener noreferrer">my last blog</a> post, I introduced an optional setting to several DBCC commands: WITH TABLERESULTS. This returns the output in tabular format, in a manner that allows the output to be consumed. As it turns out, this optional setting also works with DBCC PAGE. You can see this by examining the database information page (page 9) of the master database:</p>
<div id="wpshdo_18" class="wp-synhighlighter-outer"><div id="wpshdt_18" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_18"></a><a id="wpshat_18" class="wp-synhighlighter-title" href="#codesyntax_18"  onClick="javascript:wpsh_toggleBlock(18)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_18" onClick="javascript:wpsh_code(18)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_18" onClick="javascript:wpsh_print(18)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_18" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DBCC</span> PAGE <span class="br0">&#40;</span><span class="st0">'master'</span>, 1, 9, 3<span class="br0">&#41;</span> <span class="kw1">WITH</span> TABLERESULTS;</pre></div></div>
<p>This statement, which can be run without the trace flag, returns the data on the page in 4 columns: ParentObject, Object, Field and VALUE. As it turns out, this particular page of every database has a lot of interesting information on it. Let’s automate grabbing a specific piece of information out of this page:</p>
<div id="wpshdo_19" class="wp-synhighlighter-outer"><div id="wpshdt_19" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_19"></a><a id="wpshat_19" class="wp-synhighlighter-title" href="#codesyntax_19"  onClick="javascript:wpsh_toggleBlock(19)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_19" onClick="javascript:wpsh_code(19)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_19" onClick="javascript:wpsh_print(19)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_19" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'tempdb.dbo.#DBCCPAGE'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> <span class="kw1">DROP</span> <span class="kw1">TABLE</span> #DBCCPAGE;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> #DBCCPAGE <span class="br0">&#40;</span>
       ParentObject <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
       <span class="br0">[</span><span class="kw1">OBJECT</span><span class="br0">]</span>     <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
       Field       <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
       <span class="br0">[</span><span class="kw1">VALUE</span><span class="br0">]</span>     <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> #DBCCPAGE
<span class="kw1">EXECUTE</span> <span class="br0">&#40;</span><span class="st0">'DBCC PAGE ('</span><span class="st0">'master'</span><span class="st0">', 1, 9, 3) WITH TABLERESULTS;'</span><span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">SELECT</span> LastGoodDBCCDate <span class="sy0">=</span> <span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">DATETIME</span>, <span class="kw1">VALUE</span><span class="br0">&#41;</span>
<span class="kw1">FROM</span>   #DBCCPAGE
<span class="kw1">WHERE</span>   Field <span class="sy0">=</span> <span class="st0">'dbi_dbccLastKnownGood'</span>;</pre></div></div>
<p>This wonderful snippet of code returns the last time a successful DBCC CHECKDB was run against the master database. <strong>Whoa… how sweet is that</strong>? When you discover a server where the CHECKDB job has been failing to the point that the job only has failed entries in the job history, you can now find out just how long it’s been since it was last run successfully.</p>
<p>The “trick” to making this work is to encapsulate the DBCC command as a string, and to call it with the EXECUTE () function. This is used as part of an INSERT INTO / EXECUTE statement, so that the results from DBCC PAGE are inserted into a table (in this case a temporary table is used, although a table variable or permanent table can also be used). There are three simple steps to this process:</p>
<ol>
<li>Create a table (permanent / temporary) or table variable to hold the output.</li>
<li>Insert into this table the results of the DBCC PAGE statement by using INSERT INTO / EXECUTE.</li>
<li>Select the data that you are looking for from the table.</li>
</ol>
<p>By utilizing a cursor, you can easily spin through all of the databases on your instance to get when they last had a successful DBCC CHECKDB run against them. The following utilizes sp_MSforeachdb (which itself uses a cursor to spin through all of the databases) to do just this:</p>
<div id="wpshdo_20" class="wp-synhighlighter-outer"><div id="wpshdt_20" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_20"></a><a id="wpshat_20" class="wp-synhighlighter-title" href="#codesyntax_20"  onClick="javascript:wpsh_toggleBlock(20)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_20" onClick="javascript:wpsh_code(20)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_20" onClick="javascript:wpsh_print(20)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_20" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'tempdb.dbo.#DBCCPAGE'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> <span class="kw1">DROP</span> <span class="kw1">TABLE</span> #DBCCPAGE;
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'tempdb.dbo.#CheckDBDates'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> <span class="kw1">DROP</span> <span class="kw1">TABLE</span> #CheckDBDates;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> #DBCCPAGE <span class="br0">&#40;</span>
       ParentObject   <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
       <span class="br0">[</span><span class="kw1">OBJECT</span><span class="br0">]</span>       <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
       Field           <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span>,
       <span class="br0">[</span><span class="kw1">VALUE</span><span class="br0">]</span>         <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>255<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> #CheckDBDates <span class="br0">&#40;</span>
       database_name   sysname,
       LastCheckDB     <span class="kw1">DATETIME</span><span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">EXECUTE</span> sp_MSforeachdb <span class="st0">'
TRUNCATE TABLE #DBCCPAGE;
INSERT INTO #DBCCPAGE
   EXECUTE ('</span><span class="st0">'DBCC PAGE ('</span><span class="st0">''</span><span class="st0">'?'</span><span class="st0">''</span><span class="st0">', 1, 9, 3) WITH TABLERESULTS;'</span><span class="st0">');
INSERT INTO #CheckDBDates
SELECT '</span><span class="st0">'?'</span><span class="st0">', CONVERT(DATETIME, VALUE)
FROM   #DBCCPAGE
WHERE   Field = '</span><span class="st0">'dbi_dbccLastKnownGood'</span><span class="st0">';'</span>;
&nbsp;
<span class="kw1">SELECT</span> database_name,
       LastCheckDB
<span class="kw1">FROM</span>   #CheckDBDates;</pre></div></div>
<p>And here we have every database on your instance, and the date that DBCC CHECKDB was last run successfully against it – well, at least for the databases that sp_MSforeachdb didn’t skip (see <a href="https://www.mssqltips.com/sqlservertip/2201/making-a-more-reliable-and-flexible-spmsforeachdb">https://www.mssqltips.com/sqlservertip/2201/making-a-more-reliable-and-flexible-spmsforeachdb</a>/ for more information about this).</p>
<p>In summary, by utilizing the “WITH TABLERESULTS” option of DBCC, we can automate processes that use DBCC PAGE, instead of needing manual intervention to work your way through this.</p>
<p>In the next few installments, we’ll look at other uses of using “WITH TABLERESULTS” to automate DBCC output.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/automating-dbcc-page/">Automating DBCC Page</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dodging Phantom Reads</title>
		<link>https://sqlsolutionsgroup.com/dodging-phantom-reads/</link>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Wed, 29 Oct 2014 20:33:19 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=1651</guid>

					<description><![CDATA[<p>October… the month of Halloween. Spooky events. SQL Server has all kinds of Halloween-ish themed activities like Split Brains, Zombies, Ghosts, Phantoms, and of course Halloween itself. In this post, we’re going to mill about with phantom reads a bit. Phantoms in SQL Server are actually called “Phantom Reads”. This ectoplasmic phenomenon manifests itself when [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/dodging-phantom-reads/">Dodging Phantom Reads</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<figure id="attachment_1680" aria-describedby="caption-attachment-1680" style="width: 300px" class="wp-caption alignright"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2014/10/phantom.png"><img loading="lazy" decoding="async" class="wp-image-1680 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2014/10/phantom.png" alt="Dodging phantom reads" width="300" height="318" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2014/10/phantom.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2014/10/phantom-283x300.png 283w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-1680" class="wp-caption-text">Dodge me if you can</figcaption></figure>
<p>October… the month of Halloween. Spooky events. SQL Server has all kinds of Halloween-ish themed activities like Split Brains, Zombies, Ghosts, Phantoms, and of course Halloween itself. In this post, we’re going to mill about with phantom reads a bit.</p>
<p>Phantoms in SQL Server are actually called “Phantom Reads”. This ectoplasmic phenomenon manifests itself when an identical query being run multiple times, in a single connection, returns a different result set for each time it is run. A Phantom Read is one of the transaction isolation level concurrency events. The read uncommitted, read committed and repeatable read transaction isolation levels may exhibit Phantom Reads; the serializable and snapshot transaction isolation levels are not susceptible to this phenomenon.</p>
<p>Let’s set up a demo to see this in action. First, let’s create our sample data:<div id="wpshdo_21" class="wp-synhighlighter-outer"><div id="wpshdt_21" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_21"></a><a id="wpshat_21" class="wp-synhighlighter-title" href="#codesyntax_21"  onClick="javascript:wpsh_toggleBlock(21)" title="Click to show/hide code block">Sample Data</a></td><td align="right"><a href="#codesyntax_21" onClick="javascript:wpsh_code(21)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_21" onClick="javascript:wpsh_print(21)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_21" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">USE</span> master; 
GO 
&nbsp;
<span class="kw1">IF</span> <span class="kw2">DB_ID</span><span class="br0">&#40;</span><span class="st0">'IsolationLevelTest'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> 
<span class="kw1">BEGIN</span> 
    <span class="kw1">ALTER</span> <span class="kw1">DATABASE</span> IsolationLevelTest <span class="kw1">SET</span> S<span class="sy0">IN</span>GLE_USER <span class="kw1">WITH</span> <span class="kw1">ROLLBACK</span> <span class="kw1">IMMEDIATE</span>; 
    <span class="kw1">DROP</span> <span class="kw1">DATABASE</span> IsolationLevelTest; 
<span class="kw1">END</span>; 
<span class="kw1">CREATE</span> <span class="kw1">DATABASE</span> IsolationLevelTest; 
GO 
&nbsp;
<span class="kw1">USE</span> IsolationLevelTest; 
GO 
<span class="kw1">CREATE</span> <span class="kw1">PROCEDURE</span> dbo.<span class="me1">db_reset</span> <span class="kw1">AS</span> 
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'dbo.IsolationTests'</span>,<span class="st0">'U'</span><span class="br0">&#41;</span> <span class="kw1">IS</span> <span class="sy0">NOT</span> <span class="sy0">NULL</span> 
    <span class="kw1">DROP</span> <span class="kw1">TABLE</span> dbo.<span class="me1">IsolationTests</span>; 
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> dbo.<span class="me1">IsolationTests</span> <span class="br0">&#40;</span>
    Id   <span class="kw1">INTEGER</span> <span class="kw1">IDENTITY</span>,
    ColA <span class="kw1">CHAR</span><span class="br0">&#40;</span>1<span class="br0">&#41;</span>
<span class="br0">&#41;</span>; 
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">IsolationTests</span><span class="br0">&#40;</span>ColA<span class="br0">&#41;</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span> <span class="kw1">UNION</span> <span class="sy0">ALL</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span> <span class="kw1">UNION</span> <span class="sy0">ALL</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span> <span class="kw1">UNION</span> <span class="sy0">ALL</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span> <span class="kw1">UNION</span> <span class="sy0">ALL</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span> <span class="kw1">UNION</span> <span class="sy0">ALL</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span> <span class="kw1">UNION</span> <span class="sy0">ALL</span> 
<span class="kw1">SELECT</span> <span class="st0">'A'</span>; 
&nbsp;
<span class="kw1">IF</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span><span class="kw1">SELECT</span> 1 <span class="kw1">FROM</span> sys.<span class="me1">databases</span> <span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'IsolationLevelTest'</span> <span class="sy0">AND</span> snapshot_isolation_state <span class="sy0">=</span> 1<span class="br0">&#41;</span>
    <span class="kw1">ALTER</span> <span class="kw1">DATABASE</span> IsolationLevelTest <span class="kw1">SET</span> <span class="sy0">ALL</span>OW_SNAPSHOT_ISOLATION <span class="kw1">OFF</span>;
GO 
<span class="kw1">EXECUTE</span> dbo.<span class="me1">db_reset</span>; 
GO</pre></div></div></p>
<p>Now, let’s test phantom reads in the repeatable read transaction isolation level. Open the following 2 queries in separate query windows. Run Code Script 1, and within 10 seconds run Code Script 2.</p>
<div id="wpshdo_22" class="wp-synhighlighter-outer"><div id="wpshdt_22" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_22"></a><a id="wpshat_22" class="wp-synhighlighter-title" href="#codesyntax_22"  onClick="javascript:wpsh_toggleBlock(22)" title="Click to show/hide code block">Code Script 1</a></td><td align="right"><a href="#codesyntax_22" onClick="javascript:wpsh_code(22)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_22" onClick="javascript:wpsh_print(22)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_22" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="coMULTI">/* Execute this script from the first query window */</span>
&nbsp;
<span class="kw1">USE</span> IsolationLevelTest;
GO
<span class="kw1">SET</span> <span class="kw1">TRANSACTION</span> <span class="kw1">ISOLATION</span> <span class="kw1">LEVEL</span> REPEATABLE <span class="kw1">READ</span>;
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;
<span class="kw1">WAITFOR</span> DELAY <span class="st0">'00:00:10'</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;
<span class="kw1">ROLLBACK</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;</pre></div></div>
<div id="wpshdo_23" class="wp-synhighlighter-outer"><div id="wpshdt_23" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_23"></a><a id="wpshat_23" class="wp-synhighlighter-title" href="#codesyntax_23"  onClick="javascript:wpsh_toggleBlock(23)" title="Click to show/hide code block">Code Script 2</a></td><td align="right"><a href="#codesyntax_23" onClick="javascript:wpsh_code(23)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_23" onClick="javascript:wpsh_print(23)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_23" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="co1">-- Run this in query window 2 while Code Script 1 is running</span>
<span class="kw1">USE</span> IsolationLevelTest;
GO
<span class="kw1">UPDATE</span> dbo.<span class="me1">IsolationTests</span> <span class="kw1">SET</span> ColA <span class="sy0">=</span> <span class="st0">'W'</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;</pre></div></div>
<p>The repeatable read transaction isolation level guarantees that there will not be any updates or deletes, so the second query is blocked until the transaction in Code Script 1 has finished. You can see that the second result set is identical to the first one. Once the transaction completes, the update in Code Script 2 can run, and the third result set from Code Script 1 shows that the result set is now changed. However, the repeatable read transaction isolation level still allows inserts, which means that you can still have a phantom read. Let’s see this by changing Code Script 2 to:</p>
<div id="wpshdo_24" class="wp-synhighlighter-outer"><div id="wpshdt_24" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_24"></a><a id="wpshat_24" class="wp-synhighlighter-title" href="#codesyntax_24"  onClick="javascript:wpsh_toggleBlock(24)" title="Click to show/hide code block">Code Script 2 (Allowing Inserts)</a></td><td align="right"><a href="#codesyntax_24" onClick="javascript:wpsh_code(24)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_24" onClick="javascript:wpsh_print(24)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_24" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="co1">-- Run this in query window 2 while Code Script 1 is running</span>
<span class="kw1">USE</span> IsolationLevelTest;
GO
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">IsolationTests</span> <span class="br0">&#40;</span>ColA<span class="br0">&#41;</span>
<span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="st0">'W'</span><span class="br0">&#41;</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;</pre></div></div>
<p>Run both code scripts again (Code Script 1 first, and Code Script 2 within 10 seconds). This time, you will see that Code Script 2 completes immediately without being blocked, and when Code Script 1 finishes, it has spawned additional data in its result set. A phantom read in action.</p>
<p>If you want to hide from phantom reads completely, then you’ll need to use either the serializable or snapshot transaction isolation levels. Both of these have the same concurrency effects: No dirty reads, non-repeatable reads, or phantom reads. The difference is in how they are implemented: the serializable transaction isolation level will block all other transactions affecting this data, while the snapshot isolation level utilizes row versions to create connection-specific versions of the table for the transaction – all of these row versions will cause increased activity in the tempdb database. Let’s take a look at how the snapshot isolation level will eradicate the phantom reads. First off, we need to modify the database to accept this isolation level.</p>
<div id="wpshdo_25" class="wp-synhighlighter-outer"><div id="wpshdt_25" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_25"></a><a id="wpshat_25" class="wp-synhighlighter-title" href="#codesyntax_25"  onClick="javascript:wpsh_toggleBlock(25)" title="Click to show/hide code block">Snapshot isolation level setup</a></td><td align="right"><a href="#codesyntax_25" onClick="javascript:wpsh_code(25)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_25" onClick="javascript:wpsh_print(25)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_25" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">ALTER</span> <span class="kw1">DATABASE</span> IsolationLevelTest <span class="kw1">SET</span> <span class="sy0">ALL</span>OW_SNAPSHOT_ISOLATION <span class="kw1">ON</span>;
GO</pre></div></div>
<p>To see this in action, we will once again have two queries. Run the code from Code Script 3 in one query window, and within 10 seconds run the code from Code Script 4 in another query window.</p>
<div id="wpshdo_26" class="wp-synhighlighter-outer"><div id="wpshdt_26" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_26"></a><a id="wpshat_26" class="wp-synhighlighter-title" href="#codesyntax_26"  onClick="javascript:wpsh_toggleBlock(26)" title="Click to show/hide code block">Code Script 3</a></td><td align="right"><a href="#codesyntax_26" onClick="javascript:wpsh_code(26)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_26" onClick="javascript:wpsh_print(26)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_26" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="co1">-- Run this code in query window 1</span>
<span class="kw1">USE</span> IsolationLevelTest;
GO
<span class="kw1">SET</span> <span class="kw1">TRANSACTION</span> <span class="kw1">ISOLATION</span> <span class="kw1">LEVEL</span> SNAPSHOT;
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;
<span class="kw1">WAITFOR</span> DELAY <span class="st0">'00:00:10'</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;
<span class="kw1">ROLLBACK</span>;</pre></div></div>
<div id="wpshdo_27" class="wp-synhighlighter-outer"><div id="wpshdt_27" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_27"></a><a id="wpshat_27" class="wp-synhighlighter-title" href="#codesyntax_27"  onClick="javascript:wpsh_toggleBlock(27)" title="Click to show/hide code block">Code Script 4</a></td><td align="right"><a href="#codesyntax_27" onClick="javascript:wpsh_code(27)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_27" onClick="javascript:wpsh_print(27)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_27" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="co1">-- Run this in query window 2 while the 1st query is running</span>
<span class="kw1">USE</span> IsolationLevelTest;
GO
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">IsolationTests</span><span class="br0">&#40;</span>ColA<span class="br0">&#41;</span>
<span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="st0">'X'</span><span class="br0">&#41;</span>;
<span class="kw1">SELECT</span> <span class="sy0">*</span> <span class="kw1">FROM</span> dbo.<span class="me1">IsolationTests</span>;</pre></div></div>
<p>Notice that Code Snippet 2 was executed immediately, however the row that it inserted was not returned in the result set from Code Snippet 1.</p>
<p>And now you know how to dodge phantoms.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/dodging-phantom-reads/">Dodging Phantom Reads</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to improve SQL Server&#8217;s IO performance by up to 40%</title>
		<link>https://sqlsolutionsgroup.com/improve-io-performance/</link>
		
		<dc:creator><![CDATA[Wayne Sheffield]]></dc:creator>
		<pubDate>Tue, 12 Aug 2014 15:26:31 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=1318</guid>

					<description><![CDATA[<p>In my last article, I started off talking about checking various settings that make a performance difference prior to jumping into query tuning. This article continues the investigation into IO performance affecting settings, by jumping straight into the storage subsystem. How would you like to make a single change to your drives and have the [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/improve-io-performance/">How to improve SQL Server&#8217;s IO performance by up to 40%</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In my <a href="https://sqlsolutionsgroup.com/sql-servers-hidden-go-fast-button/">last article</a>, I started off talking about checking various settings that make a performance difference prior to jumping into query tuning. This article continues the investigation into IO performance affecting settings, by jumping straight into the storage subsystem. How would you like to make a single change to your drives and have the IO operations improve by up to 40%?</p>
<p>Just reformat the drives that contain your database data and log files.</p>
<p>If you are running on a version of Windows prior to Windows Server 2008, or if the drives were migrated to a new system without reformatting them, then you really could improve IO performance simply by reformatting the drives. Older versions of Windows will create disk partitions that default to having the boundaries based upon the ancient Cylinder/Head/Sector addressing scheme that was common in disk controllers of that era. Once these boundaries are set, the only way to change them is to reformat the drive, so migrating this drive to a Windows Server 2008 or newer server alone does not fix the issue.</p>
<h3>How reformatting the drive affects IO performance</h3>
<h4>File Allocation Size</h4>
<p>On the hard drive, the minimum amount of data that can be read or written is called a sector, which historically was a mere 512 bytes (newer drives may have sector sizes up to 4KB). A group of sectors is a cluster (no not <em>that</em> type of cluster). A drive with a 64KB cluster size (at 512 bytes per cluster) will have 128 sectors, which is also known as the file allocation size. The first 63 sectors of a drive are reserved, or hidden, and include the master boot record (MBR). Simply multiplying the 63 sectors by the sector size of 512 bytes shows that this hidden area occupies 32,256 bytes, or 31.5KB. The drive dutifully starts storing data immediately after this.</p>
<h4>SQL Server IO operations</h4>
<p>Now, consider how SQL Server performs disk IO operations – an extent at a time (an extent is 8 pages, each of which are 8KB, for a total of 64KB). To store this information on disk, with the default settings, this 64KB will start immediately after the 31.5KB and continue for 64KB… and it will span two clusters. When the drive goes to read this data, it will have to read the first cluster, and then the second cluster, in order to get all of the data needed for the extent being read from disk. When the next extent is read, it will re-read the second cluster, and read the third cluster. The wasted IO operation should be obvious.</p>
<h4>How to have SQL Server work better with disk</h4>
<p>What we need to do is to offset the beginning of the data being stored on disk to a location more conducive to how the program is operating. This offset is known as the “Partition Alignment Offset”. To be in tune with SQL Server, this value should be an increment of 64KB. However, you also need to consider the entire storage subsystem – the disks, controllers and memory. Starting with Windows Server 2008, this offset is at 1024KB – a nice increment of 64KB that also works very nicely with most RAID disks/controllers. Prior to Windows Server 2008, partition alignment offset was not explicitly performed, so this will need to be performed.</p>
<h3>Determining a drive’s partition alignment offset</h3>
<p>To determine what the partition alignment offset is for a windows basic disk, there is a very simple wmic command to run:</p>
<div id="wpshdo_28" class="wp-synhighlighter-outer"><div id="wpshdt_28" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_28"></a><a id="wpshat_28" class="wp-synhighlighter-title" href="#codesyntax_28"  onClick="javascript:wpsh_toggleBlock(28)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_28" onClick="javascript:wpsh_code(28)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_28" onClick="javascript:wpsh_print(28)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_28" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">wmic partition <span class="kw1">GET</span> BlockSize, StartingOffset, Name, <span class="kw1">INDEX</span></pre></div></div>
<p>The Index value is the same as the disk number reported in the Disk Management tool, and also from the wmic command wmic Volume. However, we tend to think in terms of drive letters, not drive indexes, so the following PowerShell script will return Partition Alignment Offset for all drives on the system that it is run on and perform the mapping from index to drive letter:</p>
<div id="wpshdo_29" class="wp-synhighlighter-outer"><div id="wpshdt_29" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_29"></a><a id="wpshat_29" class="wp-synhighlighter-title" href="#codesyntax_29"  onClick="javascript:wpsh_toggleBlock(29)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_29" onClick="javascript:wpsh_code(29)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_29" onClick="javascript:wpsh_print(29)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_29" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;">#
# <span class="co1">-------------------------------------------------------------------------------</span>
# Partition Information
# <span class="co1">-------------------------------------------------------------------------------</span>
#                                MODIFICATION <span class="kw2">LOG</span>
# <span class="co1">-------------------------------------------------------------------------------</span>
# 2012<span class="sy0">-</span>08<span class="sy0">-</span>09 WGS Initial Creation.
# 2012<span class="sy0">-</span>08<span class="sy0">-</span>11 WGS Modified <span class="kw1">TO</span> <span class="kw1">WORK</span> <span class="kw1">WITH</span> PowerShell v1.
# 2013<span class="sy0">-</span>02<span class="sy0">-</span>05 WGS Modified <span class="kw1">TO</span> <span class="kw1">GET</span> Drive Letter.
# 2014<span class="sy0">-</span>01<span class="sy0">-</span>27 WGS Modified <span class="kw1">TO</span> <span class="kw1">RETURN</span> volume blocksize.
# <span class="co1">-------------------------------------------------------------------------------</span>
#
<span class="sy0">&lt;</span>#
.<span class="kw1">PARAMETER</span> OpenInNotepad
<span class="kw1">VALUE</span> passed <span class="kw1">AS</span> $True or $False. <span class="me1">Defaults</span> <span class="kw1">TO</span> $False.
#<span class="sy0">&gt;</span>
&nbsp;
param
<span class="br0">&#40;</span>
<span class="br0">[</span><span class="kw1">BOOLEAN</span><span class="br0">]</span> $OpenInNotepad <span class="sy0">=</span> $false
<span class="br0">&#41;</span>
&nbsp;
cls
&nbsp;
<span class="kw1">FUNCTION</span> Get<span class="sy0">-</span>DriveLetter<span class="br0">&#40;</span>$PartPath<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    #Get the logical <span class="kw1">DISK</span> mapping
    $LogicalDisks <span class="sy0">=</span> Get<span class="sy0">-</span>WMIObject Win32_LogicalDiskToPartition <span class="sy0">|</span> `
        Where<span class="sy0">-</span><span class="kw1">OBJECT</span> <span class="br0">&#123;</span>$_.<span class="me1">Antecedent</span> <span class="sy0">-</span>eq $PartPath<span class="br0">&#125;</span>
    $LogicalDrive <span class="sy0">=</span> Get<span class="sy0">-</span>WMIObject Win32_LogicalDisk <span class="sy0">|</span> `
        Where<span class="sy0">-</span><span class="kw1">OBJECT</span> <span class="br0">&#123;</span>$_.__PATH <span class="sy0">-</span>eq $LogicalDisks.<span class="me1">Dependent</span><span class="br0">&#125;</span>
    $LogicalDrive.<span class="me1">DeviceID</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">FUNCTION</span> Get<span class="sy0">-</span>VolumeBlockSize<span class="br0">&#40;</span>$PartPath<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    $Drive <span class="sy0">=</span> Get<span class="sy0">-</span>DriveLetter<span class="br0">&#40;</span>$PartPath<span class="br0">&#41;</span>
    <span class="kw1">IF</span> <span class="br0">&#40;</span>$Drive <span class="sy0">-</span>gt <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        #Get the BlockSize <span class="kw1">OF</span> the volume
        $Volume <span class="sy0">=</span> Get<span class="sy0">-</span>WMIObject Win32_Volume <span class="sy0">|</span> `
            Where<span class="sy0">-</span><span class="kw1">OBJECT</span> <span class="br0">&#123;</span>$_.<span class="me1">DriveLetter</span> <span class="sy0">-</span>eq  $Drive<span class="br0">&#125;</span>
        $Volume.<span class="me1">BlockSize</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">FUNCTION</span> Get<span class="sy0">-</span>PartitionAlignment <span class="br0">&#123;</span>
    Get<span class="sy0">-</span>WMIObject Win32_DiskPartition <span class="sy0">|</span> `
        Sort<span class="sy0">-</span><span class="kw1">OBJECT</span> DiskIndex, <span class="kw1">INDEX</span> <span class="sy0">|</span> `
        Select<span class="sy0">-</span><span class="kw1">OBJECT</span> <span class="sy0">-</span>Property `
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="me1">DiskIndex</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Disk&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="kw1">INDEX</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Partition&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>Get<span class="sy0">-</span>DriveLetter<span class="br0">&#40;</span>$_.__PATH<span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Drive&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="me1">BootPartition</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;BootPartition&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N3}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="kw1">SIZE</span><span class="sy0">/</span>1Gb<span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Size_GB&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">BlockSize</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Partition_BlockSize&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>Get<span class="sy0">-</span>VolumeBlockSize<span class="br0">&#40;</span>$_.__PATH<span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Volume_BlockSize&quot;</span><span class="br0">&#125;</span>,
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">StartingOffset</span><span class="sy0">/</span>1Kb<span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Offset_KB&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">StartingOffset</span><span class="sy0">/</span>$_.<span class="me1">BlockSize</span><span class="br0">&#41;</span><span class="br0">&#125;</span>; Label<span class="sy0">=</span><span class="st0">&quot;OffsetSectors&quot;</span><span class="br0">&#125;</span>,`
            @<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="kw1">IF</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>$_.<span class="me1">StartingOffset</span> <span class="sy0">%</span> 64KB<span class="br0">&#41;</span> <span class="sy0">-</span>EQ <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="st0">&quot; Yes&quot;</span><span class="br0">&#125;</span> <span class="kw1">ELSE</span> <span class="br0">&#123;</span><span class="st0">&quot;  No&quot;</span><span class="br0">&#125;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;64KB&quot;</span><span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
&nbsp;
# Hash <span class="kw1">TABLE</span> <span class="kw1">TO</span> <span class="kw1">SET</span> the alignment <span class="kw1">OF</span> the properties in the format<span class="sy0">-</span><span class="kw1">TABLE</span>
$b <span class="sy0">=</span> `
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="kw1">DISK</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Disk&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="me1">Partition</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Partition&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="me1">Drive</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Drive&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="me1">BootPartition</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;BootPartition&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N3}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">Size_GB</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Size_GB&quot;</span>;align<span class="sy0">=</span><span class="st0">&quot;right&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">Partition_BlockSize</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;PartitionBlockSize&quot;</span>;align<span class="sy0">=</span><span class="st0">&quot;right&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">Volume_BlockSize</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;VolumeBlockSize&quot;</span>;align<span class="sy0">=</span><span class="st0">&quot;right&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">Offset_KB</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;Offset_KB&quot;</span>;align<span class="sy0">=</span><span class="st0">&quot;right&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span><span class="st0">&quot;{0:N0}&quot;</span> <span class="sy0">-</span>f <span class="br0">&#40;</span>$_.<span class="me1">OffsetSectors</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;OffsetSectors&quot;</span>;align<span class="sy0">=</span><span class="st0">&quot;right&quot;</span><span class="br0">&#125;</span>,`
@<span class="br0">&#123;</span>Expression <span class="sy0">=</span> <span class="br0">&#123;</span>$_.<span class="br0">&#123;</span>64KB<span class="br0">&#125;</span><span class="br0">&#125;</span>;Label<span class="sy0">=</span><span class="st0">&quot;64KB&quot;</span><span class="br0">&#125;</span>
&nbsp;
&nbsp;
$a <span class="sy0">=</span> Get<span class="sy0">-</span>PartitionAlignment
&nbsp;
&nbsp;
# Display formatted <span class="kw1">DATA</span> <span class="kw1">ON</span> the screen
$a <span class="sy0">|</span> Sort<span class="sy0">-</span><span class="kw1">OBJECT</span> Drive, <span class="kw1">DISK</span>, Partition <span class="sy0">|</span> Format<span class="sy0">-</span><span class="kw1">TABLE</span> $b <span class="sy0">-</span>AutoSize
&nbsp;
<span class="kw1">IF</span> <span class="br0">&#40;</span>$OpenInNotepad <span class="sy0">-</span>eq $true<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    # Export <span class="kw1">TO</span> a pipe<span class="sy0">-</span>delimited <span class="kw1">FILE</span>
    $a <span class="sy0">|</span> Sort<span class="sy0">-</span><span class="kw1">OBJECT</span> Drive, <span class="kw1">DISK</span>, Partition <span class="sy0">|</span> Export<span class="sy0">-</span>CSV $ENV:temp\PartInfo.<span class="me1">txt</span> <span class="sy0">-</span>Delimiter <span class="st0">&quot;|&quot;</span> <span class="sy0">-</span>NoTypeInformation
&nbsp;
    # <span class="kw1">OPEN</span> the <span class="kw1">FILE</span> in NotePad
    Notepad $ENV:temp\PartInfo.<span class="me1">txt</span>
<span class="br0">&#125;</span></pre></div></div>
<p>If you want to open the results in Notepad, pass in the parameter $True.</p>
<p>You may note that I said that using these wmic commands is for a Windows basic disk. If you are using a dynamic disk, you need to use alternative methods. With Windows Server 2008, you would use the tool diskdiag.exe (in earlier versions of Windows, this was called dmdiag). For either, you need to use the –V flag: dmdiag.exe –V or diskdiag.exe –V.</p>
<h3>Changing the Partition Alignment Offset</h3>
<p>To change the Partition Alignment Offset on Windows Server 2008 or higher, simply format the drive. On earlier systems, you will need to use the diskpart.exe tool to change the partition alignment offset, and then format the drive. In either case, <span style="color: #ff0000;">this is a destructive operation – you will lose all data on the drive.</span></p>
<p>For more information on disk partition alignment, refer to this TechNet article: <a href="https://technet.microsoft.com/en-us/library/dd758814%28v=sql.100%29.aspx">https://technet.microsoft.com/en-us/library/dd758814(v=sql.100).aspx</a>.</p>
<p>These steps should yield a noticeable IO performance improvement. Test it for yourself and let me know what you experience.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/improve-io-performance/">How to improve SQL Server&#8217;s IO performance by up to 40%</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
