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

<image>
	<url>https://sqlsolutionsgroup.com/wp-content/uploads/2021/01/cropped-SSG_FAVICON0002-32x32.png</url>
	<title>Jason Brimhall, Author at SQL Solutions Group</title>
	<link>https://sqlsolutionsgroup.com/author/jbrimhall/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Easy Permissions Audit</title>
		<link>https://sqlsolutionsgroup.com/easy-permissions-audit/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 13 Feb 2017 16:45:46 +0000</pubDate>
				<category><![CDATA[Security]]></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[Audit]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=3086</guid>

					<description><![CDATA[<p>Something I have written about more than a handful of times is the need to audit. When people think about audits, the first thing that comes to mind is most likely the IRS and taxes. More than taxes are audit-able. Despite that tendency to first think taxes when somebody says &#8220;audit&#8221;, I am not writing about [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/easy-permissions-audit/">Easy Permissions Audit</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Something I have written about more than a handful of times is the need to audit. When people think about audits, the first thing that comes to mind is most likely the IRS and taxes. More than taxes are audit-able. Despite that tendency to first think taxes when somebody says &#8220;audit&#8221;, I am not writing about taxes. I will typically write about the different topics within SQL Server that can be audited. Has Johnny performed a logon to the server? When was the last time the permissions to the database changed? Did somebody change an object? When was the last time stats were updated? How about auditing success and failure of your backups (or all agent jobs for that matter)? Those are the topics I will typically write about. Today, I am going to share a simple method to help perform an easy permissions audit permissions &#8211; on a manual basis.</p>
<h2>Easy Permissions Audit</h2>
<p>As the article title denotes, today I will be discussing a simple way to get quick permissions for various principals. If you are looking for a more comprehensive and human friendly report version, I recommend reading any of my many other articles on the topic such as the following article – <a href="https://bit.ly/anGB50">here</a> or <a href="https://bit.ly/pSqPJ9">here</a>. In the second of those links there is a clue as to what tool we will be using in this easy version of the audit. That tool is called sp_helprotect.</p>
<p>The stored procedure sp_helprotect is a system stored procedure from Microsoft that can help divulge permissions for various principals in a simple table result set for you. Bearing in mind that I am keeping this to a simple audit, the examples will be simplistic in nature. Without further ado, here is the easy audit for your permissions.</p>
<h3>sp_helprotect</h3>
<p>This stored procedure was introduced in SQL Server 2008 and comes with a few parameters to help narrow the results down to a specific principal and even to any object to which that principal may have been granted permissions. Here are those parameters for quick review:</p>
<p><strong>@name = </strong>This parameter is to filter your request down to a specific object or a statement that can be executed against that object (e.g. alter, create, drop)</p>
<p><strong>@username =</strong> Is the name of the principal for which permissions are returned.</p>
<p><strong>@grantorname =</strong> Is the name of the principal that granted permissions.</p>
<p><strong>@permissionarea =</strong> This is the group of grant-able permissions. There are two types of groups: object and statement. The default setting here is to return both groups.</p>
<p>The easiest way to use sp_helprotect is as follows:</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;"><span class="kw1">USE</span> TestDB; <span class="co1">--my test database...you need to change it</span>
GO
&nbsp;
<span class="kw1">EXECUTE</span> sys.<span class="kw3">SP_HELPROTECT</span></pre></div></div>
<p>Do you see how easy that is? This returns the following results for me.</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_simple.jpg"><img fetchpriority="high" decoding="async" class="aligncenter wp-image-5121 size-large" src="https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_simple-1024x339.jpg" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_simple-1024x339.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_simple-300x99.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_simple-768x254.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_simple-50x17.jpg 50w" alt="" width="560" height="185" /></a></p>
<p>Note from the results that I see results for roles and users for various different objects. This is due to how the procedure was executed – with no parameters. Using no parameters in this query, the default behavior is to return as much information as possible for all objects and principals within the database.</p>
<p>What if I only want the results for a principal named “Gargouille”? I can do that in the following way.</p>
<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;"><span class="kw1">USE</span> TestDB; <span class="co1">--my test database...you need to change it</span>
GO
&nbsp;
<span class="kw1">EXECUTE</span> sys.<span class="kw3">SP_HELPROTECT</span> 
	@username <span class="sy0">=</span> <span class="st0">'gargouille'</span></pre></div></div>
<p>Now, I will receive the following results:</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille.jpg"><img decoding="async" class="aligncenter wp-image-5120 size-large" src="https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille-1024x142.jpg" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille-1024x142.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille-300x42.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille-768x107.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille-50x7.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/helprotect_gargouille.jpg 1298w" alt="" width="560" height="78" /></a></p>
<h2>Recap</h2>
<p>There are many ways to produce an audit. Today, I have shown how one can produce a permissions audit when in a hurry that will produce a simple result set for database permissions. I want to underscore that this was at the database level and not the server level. While this is an adequate means for a quick peek into some of the objects and granted permissions, I do recommend using one of the other methods I have introduced in the other articles for ongoing complex audits and results that are somewhat prettier and more human friendly to read.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/easy-permissions-audit/">Easy Permissions Audit</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>sp_server_diagnostics &#8211; Black Box Recorder</title>
		<link>https://sqlsolutionsgroup.com/sp_server_diagnostics-black-box-recorder/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 26 Jul 2016 13:20:25 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL]]></category>
		<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[Audit]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2967</guid>

					<description><![CDATA[<p>A few months back I began a series about the SQL Black Box Recorder, that you can read here, with a promise of at least two more posts. The first article in the series laid the groundwork about the black box recorder in SQL Server. Furthermore, there was a brief introduction into the three components [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sp_server_diagnostics-black-box-recorder/">sp_server_diagnostics &#8211; Black Box Recorder</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>A few months back I began a series about the SQL Black Box Recorder, that you can read <a href="https://bit.ly/1JIyYXX">here</a>, with a promise of at least two more posts. <img decoding="async" class="alignright wp-image-2769" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2.png" alt="sp_server_diagnostics" width="325" height="247" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2.png 506w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2-300x228.png 300w" sizes="(max-width: 325px) 100vw, 325px" />The first article in the series laid the groundwork about the black box recorder in SQL Server. Furthermore, there was a brief introduction into the three components of the black box recorder. The three components as laid out in that article are: Default Trace, system_health Extended Event Session, and the sp_server_diagnostics procedure.</p>
<p>The first article went into deeper detail about the first leg of this three-legged black box recorder—the default trace. In the second article, the focus was directed to the next leg of the black box recorder—or the system_health Extended Event Session. If by some measure you are in the dark about what Extended Events is, then I recommend you read my personal blog series on the subject. There are numerous articles stepping through the subject in easy-to-digest fashion. You can find many of the articles in the following table of contents—<span style="text-decoration: underline;"><a href="https://bit.ly/XE60Days">here</a></span>.</p>
<p>The focus of this article will take on the topic of the third piece of the black box recorder, sp_server_diagnostics. I will show how this procedure is critical in gathering pertinent information that is crucial to gathering an overall picture of the system—from a default black box recorder perspective.</p>
<h2>SQL Black Box Recorder</h2>
<h3>What is the sp_server_diagnostics process?</h3>
<p>Beyond being a component of the black box for SQL Server, what exactly is this diagnostics process? The sp_server_diagnostics is much as the name implies—it is a “diagnostics” service that attempts to gather information about various events that may affect the overall health of the SQL Server instance.</p>
<p>The diagnostics process will trap various server related health (diagnostics) information related to the SQL Server instance in an effort to try and detect potential failures and errors. This diagnostics session/process traps information for five different categories by default. There is a sixth category of information for those special servers that happen to be running an Availability Group.</p>
<h4>The Six</h4>
<ul>
<li><strong>system</strong>: overall health of the server including information about spinlocks, severe processing conditions, non-yielding tasks, page faults, and CPU usage.</li>
<li><strong>resource</strong>: health of resources, specifically including physical and virtual memory, buffer pools, pages, cache and other memory objects</li>
<li><strong>query_processing</strong>: captures query processing data about worker threads, tasks, wait types, CPU intensive sessions, and blocking tasks.</li>
<li><strong>io_subsystem</strong>: health related data to IO.</li>
<li><strong>events</strong>: errors and events of interest recorded by the server, including details about ring buffer exceptions, ring buffer events about memory broker, out of memory, scheduler monitor, buffer pool, spinlocks, security, and connectivity.</li>
<li><strong>AvailabilityGroup</strong>: basic information about the AvailabilityGroup if there is an AvailabilityGroup enabled on the server.</li>
</ul>
<p>This is fantastic introductory information. As luck would have it, you can also read more about it from my <a href="https://bit.ly/1GMfikp">blog – here</a>.</p>
<h3>How to use this process?</h3>
<p>What good is any level of information if we don’t quite know how to use or consume that data? Do we consume it via trace? Do we execute the stored procedure? Do we capture the information from some other means? The answer is yes! Wait, yes to what? Yes to all of it! Let’s explore how to consume this data.</p>
<h4>Option 1</h4>
<p>The first step to learning how to consume this data is to start at probably the most basic of levels. As you have already noted, this is a stored procedure. It was probably the sp_ in the name that gave it away, right? Since it comes in the form of a stored procedure, it makes it pretty easy to figure out the first means to get the data from it—just execute it. Actually, let me clarify that just a bit. sp_server_diagnostics is a CLR stored procedure. Nonetheless, all that needs be done is execute it at this level to get to the data.</p>
<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;"><span class="kw1">EXECUTE</span> sp_server_diagnostics;</pre></div></div>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4872" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-1024x161.png" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-1024x161.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-300x47.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-768x121.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-50x8.png 50w" alt="" width="560" height="88" /></a></p>
<p>Look at that! Pretty slick! I execute the stored procedure and I can see a point in time result of the “health check” from this component of the black box recorder. Notice here that I only have five of the six categories that I had mentioned. This is due to the lack of a configured availability group (AlwaysOn) from this particular instance. Another point of interest is that the data column is not in a very friendly format for DBA consumption. This is flat text that just goes on and on. It is painful to consume in this manner.</p>
<h4>Tidy that Code</h4>
<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;"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> #ServerDiagnosticsResult
	<span class="br0">&#40;</span>
		create_time <span class="kw1">DATETIME</span>
		, component_type sysname
		, component_name sysname
		, <span class="kw1">STATE</span> <span class="kw1">INT</span>
		, state_desc sysname
		, <span class="kw1">DATA</span> XML
	<span class="br0">&#41;</span>;  
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> #ServerDiagnosticsResult
		<span class="kw1">EXECUTE</span> sp_server_diagnostics;  
&nbsp;
<span class="kw1">SELECT</span> <span class="sy0">*</span>
	<span class="kw1">FROM</span> #ServerDiagnosticsResult;
&nbsp;
<span class="kw1">DROP</span> <span class="kw1">TABLE</span> #ServerDiagnosticsResult;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> #ServerDiagnosticsResult
	<span class="br0">&#40;</span>
		create_time <span class="kw1">DATETIME</span>
		, component_type sysname
		, component_name sysname
		, <span class="kw1">STATE</span> <span class="kw1">INT</span>
		, state_desc sysname
		, <span class="kw1">DATA</span> XML
	<span class="br0">&#41;</span>;  
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> #ServerDiagnosticsResult
		<span class="kw1">EXECUTE</span> sp_server_diagnostics;  
&nbsp;
<span class="kw1">SELECT</span> <span class="sy0">*</span>
	<span class="kw1">FROM</span> #ServerDiagnosticsResult;
&nbsp;
<span class="kw1">DROP</span> <span class="kw1">TABLE</span> #ServerDiagnosticsResult;</pre></div></div>
<p>Looking at the code, you can see quickly the difference. I have changed the data column to be XML-based to better match the data being output from the stored procedure. Let’s see that in action:</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4874" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-1024x166.png" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-1024x166.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-300x49.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-768x124.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-50x8.png 50w" alt="" width="560" height="91" /></a></p>
<p>That is much better. Now I can simply click one of the data results and see a nicely formatted easy to read XML output of that component. Here is an example from the query_processing component:</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4877" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-1024x351.png" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-1024x351.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-300x103.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-768x263.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-50x17.png 50w" alt="" width="560" height="192" /></a></p>
<h4>Option 2</h4>
<p>Cool! I have just shown one means of exploring this facet of the black box recorder. Now, let’s take a look at other means to get at this particular data, beyond just executing the stored procedure. Did you know that this procedure is very closely related to Extended Events? (I am sure that you picked up on that nugget due to reading the <a href="https://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/">previous article in the series</a> or possibly the other article I mentioned <a href="https://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/">here</a>). With such a close relationship to Extended Events, it makes sense that sp_server_diagnostics also has a couple of events and is consumed by multiple sessions.</p>
<p>SQL Server comes with various default Extended Event sessions, of those sp_server_diagnostics is consumed by the system_health session as well as the hidden session for SQLDiag that is used by Windows Clustering and Availability Groups to determine server health. You already heard about the system_health (from the previous article), but few have heard about the hidden session. I will take a look at the events as well as the sessions that consume the sp_server_diagnostics data.</p>
<h4>Events</h4>
<p>First, I will share the details for each of the events related to the sp_server_diagnostics process.</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4881" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-1024x82.png" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-1024x82.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-300x24.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-768x61.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-50x4.png 50w" alt="" width="560" height="45" /></a></p>
<p>As I have shown here, you can see that these events are a part of the debug channel. In the next couple of images, I want to show some of the payload attached to these events.</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4884" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-1024x159.png" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-1024x159.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-300x47.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-768x119.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-50x8.png 50w" alt="" width="560" height="87" /></a></p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4887" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-1024x350.png" sizes="(max-width: 560px) 100vw, 560px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-1024x350.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-300x103.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-768x263.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-50x17.png 50w" alt="" width="560" height="191" /></a></p>
<p>These events show what I have shown previously with regards to output of the stored procedure. There is a consistency in the output of the diagnostics process. What I have yet to show in this data is one more piece of information that could be helpful down the road and that pertains specifically to the extended events data. That piece of information I need to share is the keyword associated with each of these events. When looking for related events, I need you to understand that the sp_server_diagnostics events are a part of the <strong>scheduling</strong> classification. There, I have said it. I just gave you a big clue to help you in your troubleshooting endeavors and the use of the diagnostics processes/events.</p>
<h4>Which Sessions then?</h4>
<p>Now that I have shown which events are related to diagnostics, I can finally show which sessions are dependent upon the diagnostics data. To show that kind of information, I have this next query to help:</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="coMULTI">/* session that is running */</span>
<span class="kw1">SELECT</span> xs.<span class="me1">name</span> <span class="kw1">AS</span> SessionName
		, xse.<span class="me1">event_name</span>
	<span class="kw1">FROM</span> sys.<span class="me1">dm_xe_session_events</span> xse
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_sessions</span> xs
			<span class="kw1">ON</span> xse.<span class="me1">event_session_address</span> <span class="sy0">=</span> xs.<span class="me1">address</span>
	<span class="kw1">WHERE</span> xse.<span class="me1">event_name</span> <span class="sy0">IN</span> <span class="br0">&#40;</span> <span class="st0">'sp_server_diagnostics_result_set'</span>,
								<span class="st0">'sp_server_diagnostics_component_result'</span> <span class="br0">&#41;</span>;
&nbsp;
<span class="coMULTI">/* sessions on the server but may be stopped */</span>
<span class="kw1">SELECT</span> ses.<span class="me1">name</span> <span class="kw1">AS</span> SessionName
		, sese.<span class="me1">name</span> <span class="kw1">AS</span> event_name
	<span class="kw1">FROM</span> sys.<span class="me1">server_event_session_events</span> sese
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">server_event_sessions</span> ses
			<span class="kw1">ON</span> ses.<span class="me1">event_session_id</span> <span class="sy0">=</span> sese.<span class="me1">event_session_id</span>
	<span class="kw1">WHERE</span> sese.<span class="me1">name</span> <span class="sy0">IN</span> <span class="br0">&#40;</span> <span class="st0">'sp_server_diagnostics_result_set'</span>,
							<span class="st0">'sp_server_diagnostics_component_result'</span> <span class="br0">&#41;</span>;</pre></div></div>
<p>When I execute the statements in the preceding query, I will receive a single result—system_health. That said, do not believe everything I just showed you with that query. SQL Server does a decent job at hiding some of the details. When I run the next query, I will see a little bit more information.</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> <span class="sy0">*</span>
	<span class="kw1">FROM</span> sys.<span class="me1">dm_xe_sessions</span>;</pre></div></div>
<p>When I run the preceding query, I will see the following two sessions (given that I have not change the default settings):</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4891" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions.png" sizes="(max-width: 916px) 100vw, 916px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions.png 916w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions-300x32.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions-768x83.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions-50x5.png 50w" alt="" width="916" height="99" /></a></p>
<p>Take note of the names of those two sessions. I showed that the system_health session is reliant upon the diagnostics events. Now, I am showing that there is another event session called “<strong>sp_server_diagnostics session</strong>“. Wait, there is more! SQL Server continues to hide stuff from us.</p>
<h4>Hidden Sessions</h4>
<p>When you have AlwaysOn configured, there is an additional hidden session that is not visible within the sessions lists inside of SQL Server. To view this hidden session, you must follow the directions shown in <a href="https://msdn.microsoft.com/en-us/library/dn135337%28v=sql.110%29.aspx?f=255&amp;MSPPError=-2147217396">this article on msdn</a>. Once you have navigated to the folder containing the hidden XEL files, you can open them in Management Studio and view the data. It is while viewing the data that you will be able to see the relationship between sp_server_diagnostics and this newly discovered trace file.</p>
<p><a class="thickbox" href="https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4894" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth.png" sizes="(max-width: 765px) 100vw, 765px" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth.png 765w, https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth-300x133.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth-50x22.png 50w" alt="" width="765" height="338" /></a></p>
<p>The payload from this image demonstrates the relationship between sp_server_diagnostics and the hidden trace file. I challenge you to take some time to explore this hidden trace file on one of your servers where AlwaysOn is configured. I know you will be thankful for the investment at some point down the road.</p>
<h3>Conclusion</h3>
<p>I have just shown a ton of info about the third component of the black box recorder—sp_server_diagnostics. This procedure may be lesser known than the first two components, but it is highly integral into the overall monitoring and health of your SQL Server instance. In this article, I have not only shown how to use sp_server_diagnostics (albeit quickly), but I have also shown that the diagnostics are heavily relied upon by other components of the black box recorder. In addition, I have shown how this component is integrated into other hidden traces that are essential in the monitoring and troubleshooting of your instance.</p>
<p>The black box recorder is real. You need to invest time in getting to know the black box recorder components and how they can be of help to you in becoming a superhero DBA.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sp_server_diagnostics-black-box-recorder/">sp_server_diagnostics &#8211; Black Box Recorder</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL Black Box Recorder part II</title>
		<link>https://sqlsolutionsgroup.com/sql-black-box-recorder-part-ii/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 06 Apr 2016 13:35:34 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL]]></category>
		<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[Audit]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2911</guid>

					<description><![CDATA[<p>A few months back I began a series, about the SQL Black Box Recorder that you can read here, with a promise of at least two more posts. The first article in the series laid the groundwork about the black box recorder in SQL Server. Furthermore, there was a brief introduction into the three components [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sql-black-box-recorder-part-ii/">SQL Black Box Recorder part II</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>A few months back I began a series, about the SQL Black Box Recorder that you can read <a href="https://bit.ly/1JIyYXX">here</a>, with a promise of at least two more posts. <img loading="lazy" decoding="async" class="alignright wp-image-2769" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2.png" alt="black box recorder" width="325" height="247" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2.png 506w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2-300x228.png 300w" sizes="(max-width: 325px) 100vw, 325px" />The first article in the series laid the groundwork about the black box recorder in SQL Server. Furthermore, there was a brief introduction into the three components of the black box recorder. The three components as laid out in that article are:</p>
<ul>
<li>Default Trace</li>
<li>system_health Extended Event Session</li>
<li>sp_server_diagnostics procedure</li>
</ul>
<p>The first article went into deeper detail about the first leg of this three-legged black box recorder &#8211; the default trace. In this article, the focus will be directed to the next leg of the black box recorder &#8211; or the system_health Extended Event Session. If by some measure you are in the dark about what Extended Events is, then I recommend you read my personal blog series on the subject. There are numerous articles stepping through the subject in easy-to-digest fashion. You can find many of the articles in the following table of contents &#8211; <a href="https://bit.ly/XE60Days">here</a>.</p>
<p>The focus of this article will not be to introduce the topic of Extended Events. Rather, it will be to introduce the system_health session and dive into it a fair bit.</p>
<h2>SQL Black Box Recorder</h2>
<h3>What is the system_health session?</h3>
<p>Beyond being a component of the black box for SQL Server, what exactly is this event session? The system_health is much as the name implies – it is a “trace” that attempts to gather information about various events that may affect the overall health of the SQL Server instance.</p>
<p>The event session will trap various events related to deadlocks, waits, clr, memory, schedulers, and reported errors. To get a better grasp of this, let’s take a look at the event session makeup based on the available metadata in the dmvs and catalog views.</p>
<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="kw1">DECLARE</span> @SessionName <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">256</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'system_health'</span>;
&nbsp;
<span class="coMULTI">/* note: this only works if the session is running and the source is &quot;server&quot; not internal or something else.
*/</span>
&nbsp;
<span class="kw1">SELECT</span> xs.<span class="me1">name</span> <span class="kw1">AS</span> SessionName
		, xs.<span class="me1">session_source</span>
		, xse.<span class="me1">event_name</span>
		, xo.<span class="me1">description</span> <span class="kw1">AS</span> EventDesc
		, xsea.<span class="me1">action_name</span>
		, xoa.<span class="me1">description</span> <span class="kw1">AS</span> ActionDesc
		, xse.<span class="me1">event_predicate</span>
		, sese.<span class="me1">predicate</span>, sese.<span class="me1">predicate_xml</span>
	<span class="kw1">FROM</span> sys.<span class="me1">dm_xe_sessions</span> xs
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_session_events</span> xse
			<span class="kw1">ON</span> xs.<span class="me1">address</span> <span class="sy0">=</span> xse.<span class="me1">event_session_address</span>
		<span class="kw1">LEFT</span> <span class="sy0">OUTER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_session_event_actions</span> xsea
			<span class="kw1">ON</span> xse.<span class="me1">event_session_address</span> <span class="sy0">=</span> xsea.<span class="me1">event_session_address</span>
				<span class="sy0">AND</span> xse.<span class="me1">event_name</span> <span class="sy0">=</span> xsea.<span class="me1">event_name</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_objects</span> xo
			<span class="kw1">ON</span> xse.<span class="me1">event_name</span> <span class="sy0">=</span> xo.<span class="me1">name</span>
				<span class="sy0">AND</span> xse.<span class="me1">event_package_guid</span> <span class="sy0">=</span> xo.<span class="me1">package_guid</span>
				<span class="sy0">AND</span> xo.<span class="me1">object_type</span> <span class="sy0">=</span> <span class="st0">'event'</span>
		<span class="kw1">LEFT</span> <span class="sy0">OUTER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_objects</span> xoa
			<span class="kw1">ON</span> xsea.<span class="me1">action_name</span> <span class="sy0">=</span> xoa.<span class="me1">name</span>
				<span class="sy0">AND</span> xsea.<span class="me1">action_package_guid</span> <span class="sy0">=</span> xoa.<span class="me1">package_guid</span>
				<span class="sy0">AND</span> xoa.<span class="me1">object_type</span> <span class="sy0">=</span> <span class="st0">'action'</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">server_event_sessions</span> ses
			<span class="kw1">ON</span> xs.<span class="me1">name</span> <span class="sy0">=</span> ses.<span class="me1">name</span>
		<span class="kw1">LEFT</span> <span class="sy0">OUTER</span> <span class="sy0">JOIN</span> sys.<span class="me1">server_event_session_events</span> sese
			<span class="kw1">ON</span> ses.<span class="me1">event_session_id</span> <span class="sy0">=</span> sese.<span class="me1">event_session_id</span>
			<span class="sy0">AND</span> xse.<span class="me1">event_name</span> <span class="sy0">=</span> sese.<span class="me1">name</span>
	<span class="kw1">WHERE</span> xs.<span class="me1">name</span> <span class="sy0">=</span> @SessionName
	<span class="kw1">ORDER</span> <span class="kw1">BY</span> xs.<span class="me1">name</span>,xse.<span class="me1">event_name</span>, xsea.<span class="me1">action_name</span>;</pre></div></div>
<p>In addition to the types of events I mentioned, there are also a few more interesting things to discover from the results of this particular query. For instance, the actions that are being employed help to gather even more information such as the callstack, tsql_callstack, database id, and sql text of the query that was executing at the moment of the event that is trapped.</p>
<p>One very peculiar event that is trapped is the sp_server_diagnostics_component_result event. Remember from earlier in this article that I noted the third leg of the black box record happens to be a very similarly named session – “sp_server_diagnostics procedure”. When I cover this third leg, it will make a little more sense. Understand, for now, that your suspicion of it being a bit more integral to the black box (than merely 1/3 of the overall black box) is confirmed.</p>
<p>This is a good set of information that can be trapped. Furthermore, this is a <strong>good set of information</strong> which can give a fairly good diagnosis of several different potential problems within your SQL Server Instance! (Yes it may seem repetitive, but I wanted to underscore the importance of the data that can be trapped.) That said, compare the types of events to those of the default trace. Take note of how many events actually overlap between the two components of the black box recorder.</p>
<p>For ease of comparison, let’s simplify that previous query to get a set of events to read without the duplication due to the actions on each event.</p>
<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">DECLARE</span> @SessionName <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">256</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'system_health'</span>;
&nbsp;
<span class="kw1">SELECT</span> xs.<span class="me1">name</span> <span class="kw1">AS</span> SessionName, xse.<span class="me1">event_name</span>
	<span class="kw1">FROM</span> sys.<span class="me1">dm_xe_sessions</span> xs
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_session_events</span> xse
			<span class="kw1">ON</span> xs.<span class="me1">address</span> <span class="sy0">=</span> xse.<span class="me1">event_session_address</span>
	<span class="kw1">WHERE</span> xs.<span class="me1">name</span> <span class="sy0">=</span> @SessionName
	<span class="kw1">ORDER</span> <span class="kw1">BY</span> xse.<span class="me1">event_name</span>;</pre></div></div>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events.png" /></p>
<p>And since I am feeling particularly generous, I have lumped the events from the two traces together in the following query:</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> @SessionName <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">256</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="st0">'system_health'</span>;
&nbsp;
<span class="kw1">SELECT</span> xs.<span class="me1">name</span> <span class="kw1">AS</span> SessionName
		, xse.<span class="me1">event_name</span> <span class="kw1">AS</span> EventName
		, mv.<span class="me1">map_value</span> <span class="kw1">AS</span> CategoryName
	<span class="kw1">FROM</span> sys.<span class="me1">dm_xe_sessions</span> xs
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_session_events</span> xse
			<span class="kw1">ON</span> xs.<span class="me1">address</span> <span class="sy0">=</span> xse.<span class="me1">event_session_address</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_objects</span> xo
			<span class="kw1">ON</span> xse.<span class="me1">event_package_guid</span> <span class="sy0">=</span> xo.<span class="me1">package_guid</span>
			<span class="sy0">AND</span> xse.<span class="me1">event_name</span> <span class="sy0">=</span> xo.<span class="me1">name</span>
			<span class="sy0">AND</span> xo.<span class="me1">object_type</span> <span class="sy0">=</span> <span class="st0">'event'</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_object_columns</span> oc
			<span class="kw1">ON</span> oc.<span class="kw2">OBJECT_NAME</span> <span class="sy0">=</span> xo.<span class="me1">name</span>
			<span class="sy0">AND</span> oc.<span class="me1">object_package_guid</span> <span class="sy0">=</span> xo.<span class="me1">package_guid</span>
			<span class="sy0">AND</span> oc.<span class="me1">name</span> <span class="sy0">=</span> <span class="st0">'KEYWORD'</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_xe_map_values</span> mv
			<span class="kw1">ON</span> oc.<span class="me1">type_name</span> <span class="sy0">=</span> mv.<span class="me1">name</span>
			<span class="sy0">AND</span> oc.<span class="me1">column_value</span> <span class="sy0">=</span> mv.<span class="me1">map_key</span>
			<span class="sy0">AND</span> oc.<span class="me1">object_package_guid</span> <span class="sy0">=</span> mv.<span class="me1">object_package_guid</span>
	<span class="kw1">WHERE</span> xs.<span class="me1">name</span> <span class="sy0">=</span> @SessionName
<span class="kw1">UNION</span> <span class="sy0">ALL</span>
<span class="coMULTI">/* events */</span>
<span class="kw1">SELECT</span> <span class="st0">'Default Trace'</span> <span class="kw1">AS</span> SessionName
		, te.<span class="me1">name</span> <span class="kw1">AS</span> EventName
		, tca.<span class="me1">name</span> <span class="kw1">AS</span> CategoryName
	<span class="kw1">FROM</span> sys.<span class="me1">traces</span> t
		<span class="sy0">CROSS</span> APPLY <span class="br0">&#40;</span> <span class="kw1">SELECT</span> <span class="kw1">DISTINCT</span> gei.<span class="me1">eventid</span>
							<span class="kw1">FROM</span> sys.<span class="kw4">FN_TRACE_GETEVENTINFO</span><span class="br0">&#40;</span>t.<span class="me1">id</span><span class="br0">&#41;</span> gei
					<span class="br0">&#41;</span> ca
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">trace_events</span> te
			<span class="kw1">ON</span> te.<span class="me1">trace_event_id</span> <span class="sy0">=</span> ca.<span class="me1">eventid</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">trace_categories</span> tca
			<span class="kw1">ON</span> te.<span class="me1">category_id</span> <span class="sy0">=</span> tca.<span class="me1">category_id</span>
	<span class="kw1">WHERE</span> t.<span class="me1">is_default</span> <span class="sy0">=</span> 1
	<span class="kw1">ORDER</span> <span class="kw1">BY</span> EventName;</pre></div></div>
<p>That should help to compare the 17 events from the system_health session and the 34 from the default trace with a little more ease and speed. The events from the two sessions are rather complimentary to each as they help to construct the SQL Server Black Box recorder.</p>
<h3>How to use this session</h3>
<p>With the events trapped by this session, there are a few ways to use the trapped data that should stand out pretty easily. To me, the quick application of the data from this session can come from the review of deadlocks, reported errors, or even waits analysis. Using the deadlock as probably the most common problem people will want to troubleshoot, this information is suddenly much more valuable and easy to access (no more need for that trace flag). Since the system_health is now trapping the deadlock by default, one could quickly access the deadlock graph from the event data and proceed to troubleshooting. More information on getting that deadlock graph can be found <a href="https://sqlsolutionsgroup.com/wean-off-sql-profiler-part-1/">here </a>and <a href="https://blog.waynesheffield.com/wayne/code-library/deadlocks/shred-deadlock-graph/">here</a>.</p>
<p>Learn to use the data made available through this member of the black box recorder. Becoming familiar with this tool (and additionally with Extended Events) will make you a rock-star in the office. The information needed to troubleshoot most problems is right at your fingertips through the use of the different pieces of the black box recorder. If it is not available there, then more than likely it can be made available through a bit of tinkering with Extended Events. Get to know the tools and be that rock-star DBA.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sql-black-box-recorder-part-ii/">SQL Black Box Recorder part II</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Indexed Views &#8211; Performance Panacea or Plight</title>
		<link>https://sqlsolutionsgroup.com/indexed-view/</link>
					<comments>https://sqlsolutionsgroup.com/indexed-view/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 28 Jan 2016 13:50:48 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<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[Database Administration]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2803</guid>

					<description><![CDATA[<p>Indexed View(s) An indexed view is a view where the result set from the query (the view definition) becomes materialized in lieu of the virtual table result set of a standard (non-indexed) view. Many times we see that an indexed view would be created to help improve performance. Far too often, an indexed view is created without consideration for [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/indexed-view/">Indexed Views &#8211; Performance Panacea or Plight</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2><img loading="lazy" decoding="async" class="alignleft wp-image-2805" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/binocular_night-1024x500.jpg" alt="indexed view" width="307" height="150" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/binocular_night-1024x500.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/binocular_night-300x147.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/binocular_night-768x375.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/binocular_night-1536x751.jpg 1536w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/binocular_night.jpg 1588w" sizes="(max-width: 307px) 100vw, 307px" />Indexed View(s)</h2>
<p>An indexed view is a view where the result set from the query (the view definition) becomes materialized in lieu of the virtual table result set of a standard (non-indexed) view. Many times we see that an indexed view would be created to help improve performance. Far too often, an indexed view is created without consideration for the costs of the indexed view. In this article, I hope to cover some of the more important costs that are frequently overlooked when considering an indexed view as a performance panacea.</p>
<h3>The Setup</h3>
<p>To demonstrate the overlooked costs of indexed views, I have decided to use the AdventureWorks2014 database (if you don&#8217;t have this sample database, you can get your copy <a href="https://bit.ly/Aworksdb">here</a>). I will create a view in that database and then I will add a few indexes to that view. Prior to sharing the entire setup, and like all good DBAs, I need to first grab a baseline. For this baseline, I am doing nothing terribly complex. I will just grab table sizes and storage information for the entire database.</p>
<p>Here are my results for the size of the objects within the AdventureWorks2014 database:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-2807 " src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_start.jpg" alt="Tablesize_start" width="907" height="143" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_start.jpg 1927w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_start-300x47.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_start-1024x162.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_start-768x121.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_start-1536x242.jpg 1536w" sizes="(max-width: 907px) 100vw, 907px" /></p>
<p>These results show that the largest object in the database happens to be the Person.Person table at just about 30MB. Not terribly large, but the database is not terribly large as a whole. Let&#8217;s see what happens when I add a materialized view, based on the Person.Person table, to the mix. Here is the definition of that view along with the indexes that I will add to help the performance of some essential production related queries.</p>
<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">USE</span> <span class="br0">[</span>AdventureWorks2014<span class="br0">]</span>;
GO
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">VIEW</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>vPerson<span class="br0">]</span>
<span class="kw1">WITH</span> SCHEMAB<span class="sy0">IN</span>D<span class="sy0">IN</span>G
<span class="kw1">AS</span>
	<span class="kw1">SELECT</span> pp.<span class="me1">BusinessEntityID</span>
			, pp.<span class="me1">FirstName</span>
			, pp.<span class="me1">LastName</span>
			, sp.<span class="br0">[</span>StateProvinceID<span class="br0">]</span>
			, sp.<span class="br0">[</span>StateProvinceCode<span class="br0">]</span>
			, sp.<span class="br0">[</span>IsOnlyStateProvinceFlag<span class="br0">]</span>
			, sp.<span class="br0">[</span>Name<span class="br0">]</span> <span class="kw1">AS</span> <span class="br0">[</span>StateProvinceName<span class="br0">]</span>
			, sp.<span class="br0">[</span>TerritoryID<span class="br0">]</span>
			, cr.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span>
			, cr.<span class="br0">[</span>Name<span class="br0">]</span> <span class="kw1">AS</span> <span class="br0">[</span>CountryRegionName<span class="br0">]</span>
			, pbe.<span class="me1">AddressTypeID</span>
			, pp.<span class="me1">AdditionalContactInfo</span>
			, pp.<span class="me1">Demographics</span>
		<span class="kw1">FROM</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>StateProvince<span class="br0">]</span> sp
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>CountryRegion<span class="br0">]</span> cr
				<span class="kw1">ON</span> sp.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span> <span class="sy0">=</span> cr.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">Address</span> pa
				<span class="kw1">ON</span> sp.<span class="me1">StateProvinceID</span> <span class="sy0">=</span> pa.<span class="me1">StateProvinceID</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">BusinessEntityAddress</span> pbe
				<span class="kw1">ON</span> pbe.<span class="me1">AddressID</span> <span class="sy0">=</span> pa.<span class="me1">AddressID</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">Person</span> pp
				<span class="kw1">ON</span> pp.<span class="me1">BusinessEntityID</span> <span class="sy0">=</span> pbe.<span class="me1">BusinessEntityID</span>
		<span class="kw1">WHERE</span> pbe.<span class="me1">AddressTypeID</span> <span class="sy0">=</span> <span class="nu0">2</span>;
&nbsp;
GO
&nbsp;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">UNIQUE</span> <span class="kw1">CLUSTERED</span> <span class="kw1">INDEX</span> CI_vPersonID <span class="kw1">ON</span> Person.<span class="me1">vPerson</span><span class="br0">&#40;</span>BusinessEntityID<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> IX_vPersonName <span class="kw1">ON</span> Person.<span class="me1">vPerson</span><span class="br0">&#40;</span>FirstName,LastName<span class="br0">&#41;</span>;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> IX_vPersonState <span class="kw1">ON</span> Person.<span class="me1">vPerson</span><span class="br0">&#40;</span>FirstName,LastName,StateProvinceID,StateProvinceCode,StateProvinceName<span class="br0">&#41;</span>;</pre></div></div>
<p>After executing all of that code to create this new view with its indexes, I have the following size results:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-2809" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_post.jpg" alt="Tablesize_post" width="908" height="144" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_post.jpg 1923w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_post-300x48.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_post-1024x162.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_post-768x122.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/Tablesize_post-1536x244.jpg 1536w" sizes="(max-width: 908px) 100vw, 908px" /></p>
<p>The creation of this view has chewed up a bunch of storage. It has jumped right up to the number two spot on the biggest objects list within this database. You can see that differences by comparing the highlighted rows to the previous image. The vPerson view is highlighted in red in this second image to help point it out quickly.</p>
<p>Surely this must be a contrived example and people don&#8217;t really do this in the real world, right? The answer to that is simply: NO! It DOES happen. I see situations like this all too often. Far too often, large text fields are added to an indexed view to make retrieval faster. I have mimicked that by adding in two XML columns from the Person.Person table. This is definitely overkill because a simple join back to the table based on the BusinessEntityID would get me those two columns. All I have effectively done is duplicated data being stored and I have achieved that at the low low cost of increased storage of 25% for this small database. If you are curious, the column count between the Person.Person table and this new view is 13 columns each.</p>
<p>I call the 25% increase storage cost a significant increase. An increase of 25% in storage for a single materialized view is not an uncommon occurrence. I have seen multi-terabyte databases with 25% of the total data storage being caused by a single view. If you are tight on storage, any unexpected data volume increase can cause a non-linear growth in data requirements to occur just because of the presence of indexed views. Take that into consideration when presented with an option to either performance tune the code or to take a short-cut and create an indexed view.</p>
<h3>Band-aid Performance</h3>
<p>I alluded to the use of indexed views as a cog to help improve performance. This is done by taking the query that sucks and turning it into a view. The thought is that it will run faster because an index is created specifically for that data set. Generally the performance gains from using an indexed view, to camouflage the bad query, are seen when the query is complex. Unfortunately, the query I provided for this article is not terribly complex. Due to the simplicity of the first example, let&#8217;s look first at the execution plan for another query that runs terribly slow but is also not terribly complex:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-2836" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/view2idxnewplan-1024x801.jpg" alt="view2idxnewplan" width="669" height="523" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/view2idxnewplan-1024x801.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/view2idxnewplan-300x235.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/view2idxnewplan-768x601.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/view2idxnewplan.jpg 1382w" sizes="(max-width: 669px) 100vw, 669px" /></p>
<p>There are a few table spools and index scans. The most costly operator of the bunch appears to be a merge join with a many-to-many join operation. The indexed view in this case does give me a very significant improvement on this query (look at that estimated cost and then the estimated number of rows). What if I could tune the query a little and avoid the all of storage cost? Let&#8217;s see!</p>
<p>Consider the base query for this new view:</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> pp.<span class="me1">BusinessEntityID</span>
			, pp.<span class="me1">FirstName</span>
			, pp.<span class="me1">LastName</span>
			, sp.<span class="br0">[</span>StateProvinceID<span class="br0">]</span>
			, sp.<span class="br0">[</span>StateProvinceCode<span class="br0">]</span>
			, sp.<span class="br0">[</span>IsOnlyStateProvinceFlag<span class="br0">]</span>
			, sp.<span class="br0">[</span>Name<span class="br0">]</span> <span class="kw1">AS</span> <span class="br0">[</span>StateProvinceName<span class="br0">]</span>
			, sp.<span class="br0">[</span>TerritoryID<span class="br0">]</span>
			, cr.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span>
			, cr.<span class="br0">[</span>Name<span class="br0">]</span> <span class="kw1">AS</span> <span class="br0">[</span>CountryRegionName<span class="br0">]</span>
			, pbe.<span class="me1">AddressTypeID</span>
			, pp.<span class="me1">AdditionalContactInfo</span>
			, pp.<span class="me1">Demographics</span>
		<span class="kw1">FROM</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>StateProvince<span class="br0">]</span> sp 
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>CountryRegion<span class="br0">]</span> cr
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>sp.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>cr.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">Address</span> pa
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>sp.<span class="me1">StateProvinceID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pa.<span class="me1">StateProvinceID</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">BusinessEntityAddress</span> pbe
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pbe.<span class="me1">AddressID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pa.<span class="me1">AddressID</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">Person</span> pp
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pp.<span class="me1">BusinessEntityID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pbe.<span class="me1">BusinessEntityID</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
		<span class="kw1">WHERE</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pbe.<span class="me1">AddressTypeID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="nu0">2</span>;</pre></div></div>
<p>Looking at the query, you may be asking yourself why use so many trim functions on each of the joins? This is an extreme that can be easily fixed. None of the fields in the joins should need to be trimmed since they are all numeric in this case. Starting there and removing all of the function use in the joins should provide significant improvements in query speed and without the use of a view. Testing it out would yield similar performance results to the first view in this article. This small change would cause the query to complete in 1 second compared to about 90 seconds. That is a huge gain, and without the added cost of increased storage use.</p>
<p>Do I really see stuff like this in the field? Yes! Spending a little time to fix the root of the problem rather than looking for a quick fix and performance can be spectacular. There are times, though, that an indexed view may be an absolute requirement. That would be perfectly fine. There are times when it is warranted and there is no way around it. If an indexed view is an absolute must, then there are a couple more considerations to be taken into account.</p>
<h3>Disappearing Act</h3>
<p>I showed previously that the indexed view requires storage space and showed that the new view created quickly claimed its place as the second largest object within the database. Now, to stage the next segment, I will show once again that the indexes are present and consuming disk space. This can be shown via the following query:</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;"><span class="kw1">SELECT</span> o.<span class="me1">name</span> <span class="kw1">AS</span> ObjName
		, i.<span class="me1">name</span> <span class="kw1">AS</span> IdxName
		, <span class="kw2">SUM</span><span class="br0">&#40;</span>ps.<span class="me1">page_count</span><span class="br0">&#41;</span> <span class="kw1">AS</span> page_count
		, <span class="kw2">SUM</span><span class="br0">&#40;</span>ps.<span class="me1">record_count</span><span class="br0">&#41;</span> <span class="kw1">AS</span> record_count
		, <span class="kw2">SUM</span><span class="br0">&#40;</span>ps.<span class="me1">page_count</span><span class="br0">&#41;</span> <span class="sy0">/</span> 128.0 <span class="kw1">AS</span> SizeMB
	<span class="kw1">FROM</span> sys.<span class="me1">indexes</span> i
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">objects</span> o
			<span class="kw1">ON</span> i.<span class="kw2">OBJECT_ID</span> <span class="sy0">=</span> o.<span class="kw2">OBJECT_ID</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_db_index_physical_stats</span><span class="br0">&#40;</span><span class="kw2">DB_ID</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="sy0">NULL</span>, <span class="sy0">NULL</span>, <span class="sy0">NULL</span>,
													<span class="st0">'detailed'</span><span class="br0">&#41;</span> ps
			<span class="kw1">ON</span> ps.<span class="kw2">OBJECT_ID</span> <span class="sy0">=</span> o.<span class="kw2">OBJECT_ID</span>
	<span class="kw1">WHERE</span> o.<span class="me1">name</span> <span class="sy0">LIKE</span> <span class="st0">'vperson%'</span>
	<span class="kw1">GROUP</span> <span class="kw1">BY</span> o.<span class="me1">name</span>
		, i.<span class="me1">name</span>;</pre></div></div>
<p>And the results of that query should look something like the following (quick reminder that I created a new indexed view for the second demo and these results will be based on that second view):</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-2833" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/vperson2-1024x231.jpg" alt="vperson2" width="669" height="151" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/vperson2-1024x231.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/vperson2-300x68.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/vperson2-768x173.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/vperson2.jpg 1052w" sizes="(max-width: 669px) 100vw, 669px" /></p>
<p>Now that we know the index is present and consuming space, time to make a change to the view and see what happens. I am proceeding under the premise that I have determined that including the two XML columns in the view are completely unnecessary and are the cause of too much space consumption. I can reap the benefits of the view at a fraction of the cost if I ALTER the view and remove those columns. So I will proceed by issuing the following ALTER statement:</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">ALTER</span> <span class="kw1">VIEW</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>vPerson2<span class="br0">]</span>
<span class="kw1">WITH</span> SCHEMAB<span class="sy0">IN</span>D<span class="sy0">IN</span>G
<span class="kw1">AS</span>
	<span class="kw1">SELECT</span> pp.<span class="me1">BusinessEntityID</span>
			, pp.<span class="me1">FirstName</span>
			, pp.<span class="me1">LastName</span>
			, sp.<span class="br0">[</span>StateProvinceID<span class="br0">]</span>
			, sp.<span class="br0">[</span>StateProvinceCode<span class="br0">]</span>
			, sp.<span class="br0">[</span>IsOnlyStateProvinceFlag<span class="br0">]</span>
			, sp.<span class="br0">[</span>Name<span class="br0">]</span> <span class="kw1">AS</span> <span class="br0">[</span>StateProvinceName<span class="br0">]</span>
			, sp.<span class="br0">[</span>TerritoryID<span class="br0">]</span>
			, cr.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span>
			, cr.<span class="br0">[</span>Name<span class="br0">]</span> <span class="kw1">AS</span> <span class="br0">[</span>CountryRegionName<span class="br0">]</span>
			, pbe.<span class="me1">AddressTypeID</span>
		<span class="kw1">FROM</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>StateProvince<span class="br0">]</span> sp 
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> <span class="br0">[</span>Person<span class="br0">]</span>.<span class="br0">[</span>CountryRegion<span class="br0">]</span> cr
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>sp.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>cr.<span class="br0">[</span>CountryRegionCode<span class="br0">]</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">Address</span> pa
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>sp.<span class="me1">StateProvinceID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pa.<span class="me1">StateProvinceID</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">BusinessEntityAddress</span> pbe
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pbe.<span class="me1">AddressID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pa.<span class="me1">AddressID</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> Person.<span class="me1">Person</span> pp
				<span class="kw1">ON</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pp.<span class="me1">BusinessEntityID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pbe.<span class="me1">BusinessEntityID</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
		<span class="kw1">WHERE</span> <span class="kw2">RTRIM</span><span class="br0">&#40;</span><span class="kw2">LTRIM</span><span class="br0">&#40;</span>pbe.<span class="me1">AddressTypeID</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">=</span> 2
;
&nbsp;
GO</pre></div></div>
<p>Take note of how long this ALTER command takes to complete &#8211; nearly instantaneous.  That rocks! Right? Let&#8217;s look at the indexes to make sure they are still in working order and don&#8217;t require a defrag. Based on that, I will re-run that query to check the indexes and sizes &#8211; for giggles.</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">SELECT</span> o.<span class="me1">name</span> <span class="kw1">AS</span> ObjName
		, i.<span class="me1">name</span> <span class="kw1">AS</span> IdxName
		, <span class="kw2">SUM</span><span class="br0">&#40;</span>ps.<span class="me1">page_count</span><span class="br0">&#41;</span> <span class="kw1">AS</span> page_count
		, <span class="kw2">SUM</span><span class="br0">&#40;</span>ps.<span class="me1">record_count</span><span class="br0">&#41;</span> <span class="kw1">AS</span> record_count
		, <span class="kw2">SUM</span><span class="br0">&#40;</span>ps.<span class="me1">page_count</span><span class="br0">&#41;</span> <span class="sy0">/</span> 128.0 <span class="kw1">AS</span> SizeMB
	<span class="kw1">FROM</span> sys.<span class="me1">indexes</span> i
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">objects</span> o
			<span class="kw1">ON</span> i.<span class="kw2">OBJECT_ID</span> <span class="sy0">=</span> o.<span class="kw2">OBJECT_ID</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">dm_db_index_physical_stats</span><span class="br0">&#40;</span><span class="kw2">DB_ID</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="sy0">NULL</span>, <span class="sy0">NULL</span>, <span class="sy0">NULL</span>,
													<span class="st0">'detailed'</span><span class="br0">&#41;</span> ps
			<span class="kw1">ON</span> ps.<span class="kw2">OBJECT_ID</span> <span class="sy0">=</span> o.<span class="kw2">OBJECT_ID</span>
	<span class="kw1">WHERE</span> o.<span class="me1">name</span> <span class="sy0">LIKE</span> <span class="st0">'vperson%'</span>
	<span class="kw1">GROUP</span> <span class="kw1">BY</span> o.<span class="me1">name</span>
		, i.<span class="me1">name</span>;</pre></div></div>
<p>This time when the query completes, I get a nice little surprise: I no longer have any indexes on that view. Changing the view definition instantly drops any indexes that were built on that view. If this is done in a production system, imagine the implications and problems that could arise.</p>
<h3>Conclusion</h3>
<p>In this article, I have covered indexed views and three different considerations that are often overlooked when looking to implement a materialized view. The three considerations for indexed views, as discussed, are: storage, changes to the view, and the band-aid effect. Overlooking the cost of storage can have serious repercussions on the production environment. Implementing an indexed view without attempting to tune the code first could lead to overlooking the storage cost and could end up just being a waste of resources. The last tidbit is that any change to an indexed view will drop the indexes. That is an easily overlooked feature of indexed views. If you forget to recreate the indexes on the view after making changes, you could be looking at a production outage.</p>
<p>There are a couple more critical considerations for indexed views that are often overlooked as well. These additional considerations are blocking, deadlocking, and maintenance. These considerations will be discussed further in a future article.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/indexed-view/">Indexed Views &#8211; Performance Panacea or Plight</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/indexed-view/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Disk Space and SQL Server</title>
		<link>https://sqlsolutionsgroup.com/sql-disk-space/</link>
					<comments>https://sqlsolutionsgroup.com/sql-disk-space/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 21 Jan 2016 12:20:30 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<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[Database Administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2785</guid>

					<description><![CDATA[<p>Disk Space in SQL Server One of the frequently required job functions of the database administrator is to track disk space consumption. Whether this requirement comes from management or from a learning opportunity after a production outage, the need exists. As a hard working DBA, you want to make sure you hit all of the notes [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sql-disk-space/">Disk Space and SQL Server</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2><img loading="lazy" decoding="async" class="wp-image-2790 alignright" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/sunburst_space-1024x836.jpg" alt="sunburst_space" width="365" height="298" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/sunburst_space-1024x836.jpg 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/sunburst_space-300x245.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/sunburst_space-768x627.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/sunburst_space.jpg 1059w" sizes="(max-width: 365px) 100vw, 365px" />Disk Space in SQL Server</h2>
<p>One of the frequently required job functions of the database administrator is to track disk space consumption. Whether this requirement comes from management or from a learning opportunity after a production outage, the need exists.</p>
<p>As a hard working DBA, you want to make sure you hit all of the notes to make management sing your praises. Knowing just when the database may fill the drives and prevent a production outage just happens to be one of those sharp notes that could result in a raise and management singing hallelujah. The problem is, how do you do it from within SQL Server? You are just a DBA after all and the disk system is not your domain, right?</p>
<p>Trying to figure it out, you come across a pretty cool function within SQL Server. The name of the function is <a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-os-volume-stats-transact-sql?view=sql-server-2017">sys.dm_os_volume_stats</a>. Bonus! This is an excellent discovery, right? Let’s see just how it might work. First a sample query:</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> <span class="kw1">DISTINCT</span>  ovs.<span class="me1">logical_volume_name</span> <span class="kw1">AS</span> VolumeName
		, ovs.<span class="me1">volume_mount_point</span> <span class="kw1">AS</span> DiskDrive
		, ovs.<span class="me1">available_bytes</span> <span class="kw1">AS</span> FreeSpace
		, ovs.<span class="me1">total_bytes</span> <span class="kw1">AS</span> CurrentSize
	<span class="kw1">FROM</span> sys.<span class="me1">master_files</span> mf
		<span class="sy0">CROSS</span> APPLY sys.<span class="me1">dm_os_volume_stats</span><span class="br0">&#40;</span>mf.<span class="me1">database_id</span>, mf.<span class="kw2">FILE_ID</span><span class="br0">&#41;</span> ovs;</pre></div></div>
<p>If I run that on my local system, I <em>might</em> end up with something that looks like the following:</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1.png" /></p>
<p>Looking at the image you may be wondering to yourself right now why I have highlighted a couple of things. You may also be wondering why I used the word “might” in the previous paragraph as well. The reasoning will become more evident as we progress. For now, you have resolved to continue testing the script so execute it again and end up with something that <em>may</em> look like the following (for the same server):</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2.png" /></p>
<p>Whoa! What just happened there? Why are there two listings for the C: drive? Why does each register a different value for the FreeSpace column? In addition without any additional usage on the C drive (as verified through other tools) the FreeSpace is changing between executions as well as within the same execution. This is problematic, so you continue testing:</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3.png" /></p>
<p>And yet again!</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4.png" /></p>
<p>This can’t be correct, can it? Just for giggles let’s modify it just a bit to see if there are any additional clues. Using the following changed script, hopefully a clue will help shed some light on this:</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">SELECT</span> ovs.<span class="me1">logical_volume_name</span> <span class="kw1">AS</span> VolumeName
		, ovs.<span class="me1">volume_mount_point</span> <span class="kw1">AS</span> DiskDrive
		, ovs.<span class="me1">available_bytes</span> <span class="kw1">AS</span> FreeSpace
		, ovs.<span class="me1">total_bytes</span> <span class="kw1">AS</span> CurrentSize
	<span class="kw1">FROM</span> sys.<span class="me1">master_files</span> mf
		<span class="sy0">CROSS</span> APPLY sys.<span class="me1">dm_os_volume_stats</span><span class="br0">&#40;</span>mf.<span class="me1">database_id</span>, mf.<span class="kw2">FILE_ID</span><span class="br0">&#41;</span> ovs;</pre></div></div>
<p>This script yields the following potential results:</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts-754x1024.jpg" /></p>
<p>Look at the different highlighted areas! There are three different values for FreeSpace for the C: drive in this particular execution. The case of the C: drive plays no role in whether the value is recorded differently or not. This seems to be more of a bug within the dynamic management function. From execution to execution, using this particular method, one could end up with duplicate entries but distinct values. The sort of the execution could be returned differently (though we could fix that).</p>
<p>All of these tests were run on my local machine and I really do only have one C: drive. I should never receive multiple entries back for any drive. If using this particular DMF to track space usage, it could be somewhat problematic if the duplicate drive data pops up. How do we get around it, you ask? Here is another example that I have that has not yet produced this duplication:</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">WITH</span> presel <span class="kw1">AS</span> <span class="br0">&#40;</span><span class="kw1">SELECT</span> database_id, <span class="kw2">FILE_ID</span>,<span class="kw1">LEFT</span><span class="br0">&#40;</span>mf1.<span class="me1">physical_name</span>,3<span class="br0">&#41;</span> <span class="kw1">AS</span> Volume, ROW_NUMBER<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">OVER</span> <span class="br0">&#40;</span>PARTITION <span class="kw1">BY</span> <span class="kw1">LEFT</span><span class="br0">&#40;</span>mf1.<span class="me1">physical_name</span>,3<span class="br0">&#41;</span> <span class="kw1">ORDER</span> <span class="kw1">BY</span> mf1.<span class="me1">database_id</span><span class="br0">&#41;</span> <span class="kw1">AS</span> RowNum
					<span class="kw1">FROM</span> sys.<span class="me1">master_files</span> mf1<span class="br0">&#41;</span>
,roundtwo <span class="kw1">AS</span> <span class="br0">&#40;</span><span class="kw1">SELECT</span> <span class="kw1">DISTINCT</span> pr.<span class="me1">database_id</span>, pr.<span class="kw2">FILE_ID</span>
				<span class="kw1">FROM</span> presel pr
				<span class="kw1">WHERE</span> pr.<span class="me1">RowNum</span> <span class="sy0">=</span> 1<span class="br0">&#41;</span>
&nbsp;
<span class="kw1">SELECT</span> ovs.<span class="me1">logical_volume_name</span> <span class="kw1">AS</span> VolumeName
		, ovs.<span class="me1">volume_mount_point</span> <span class="kw1">AS</span> DiskDrive
		, ovs.<span class="me1">available_bytes</span> <span class="kw1">AS</span> FreeSpace
		, ovs.<span class="me1">total_bytes</span> <span class="kw1">AS</span> CurrentSize
	<span class="kw1">FROM</span> roundtwo mf
		<span class="sy0">CROSS</span> APPLY sys.<span class="me1">dm_os_volume_stats</span><span class="br0">&#40;</span>mf.<span class="me1">database_id</span>, mf.<span class="kw2">FILE_ID</span><span class="br0">&#41;</span> ovs;</pre></div></div>
<p>Using this version of the script is not terribly more complex, but it will prove to be more reliable. You can see I used some CTEs to provide a little trickery and ensure that I limit my results. What if it is a mount point or a non-standard drive letter? I have not tested that. Let me know how that goes. As you can see, I am restricting the drive selection by using the row_number function against the drive letter.</p>
<p>For alternative reliable methods to find your disk space consumption, I would recommend something different because it is tried and tested. I would recommend using a wmi call to fetch the data. Samples are provided as follows:</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="coMULTI">/* for mount points, something like this */</span>
<span class="kw1">EXECUTE</span> sys.<span class="me1">xp_cmdshell</span> <span class="st0">'wmic volume get name, freespace, capacity, label'</span>
<span class="coMULTI">/* the base wmi query that does not support mount points */</span>
<span class="kw1">EXECUTE</span> xp_cmdshell <span class="st0">'wmic logicaldisk get name,freespace,size,volumename,blocksize'</span></pre></div></div>
<p>Easy peasy, right? Have at it and try tracking your disk space.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sql-disk-space/">Disk Space and SQL Server</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/sql-disk-space/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Black Box Recorder</title>
		<link>https://sqlsolutionsgroup.com/sql-black-box-recorder/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 12 Jan 2016 19:33:32 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL]]></category>
		<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[Audit]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2764</guid>

					<description><![CDATA[<p>Across many professions and industries there is often a need to have some sort of device that &#8220;audits&#8221; everything that happens with a device or process. We are probably all quite familiar with the infamous black box recorders used by the passenger airline and train industries. It is also quite possibly fairly common knowledge that [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sql-black-box-recorder/">SQL Black Box Recorder</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="https://bit.ly/1ZhJI1f"><img loading="lazy" decoding="async" class="alignright wp-image-2769" src="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2.png" alt="trace blackbox" width="280" height="213" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2.png 506w, https://sqlsolutionsgroup.com/wp-content/uploads/2016/01/blackbox2-300x228.png 300w" sizes="(max-width: 280px) 100vw, 280px" /></a>Across many professions and industries there is often a need to have some sort of device that &#8220;audits&#8221; everything that happens with a device or process. We are probably all quite familiar with the infamous black box recorders used by the passenger airline and train industries. It is also quite possibly fairly common knowledge that many pace makers perform the same sort of functionality &#8211; on a smaller scale. Various metrics and data points are registered and recorded somewhere. Whether to a local storage device or whether the device phones home to some other remote location, it is recorded.</p>
<p>We often pontificate about the what-ifs for a black box recorder within SQL Server, right? We wish and dream and go about creating our own little recorder to suit the requirements we deem necessary for successful monitoring of the server for the just-in-case scenario. Well, the truth of the matter is that we really don&#8217;t need to go to such great lengths to create a &#8220;black box recorder&#8221; because Microsoft has already done all of that for us.</p>
<p>Wait, what? Yes, that’s right! Truth be told this shouldn’t be much news for most Senior Level data professionals working with SQL Server for the past few years. But if you are new to the product, this might be good news for you. Then again, it might just be bad news depending on your take.</p>
<p>Very much like what you may find with the airline industry, the black box recorder in SQL Server is not just a single method (device) implemented to capture all of the desired data points. On a passenger jet, you may find that there are three or more such devices that contribute to the capture and recording of the in-flight data. In SQL Server, there are three major processes that help capture our in-flight data. Over the next few articles I will discuss each of these processes. These processes include:</p>
<ul>
<li>Default Trace</li>
<li>system_health Extended Event Session</li>
<li>sp_server_diagnostics procedure</li>
</ul>
<p>This multi-tiered approach does provide a sort of fail-safe system. If one should be disabled, there still remain up to two more processes that may be running. That said, each of these can be disabled but it does take a bit of an overt effort. And since it does require somebody to put out effort to try and disable each of the black box components, you could potentially capture the culprit via audits from the other components or via an explicit audit that you create for these types of purposes.</p>
<p>Since this will be something to discuss over a few articles, I will break out each process into an individual article. For today, I will discuss the default trace.</p>
<h2>Default Trace</h2>
<p>The <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/default-trace-enabled-server-configuration-option?view=sql-server-2017">default trace</a> by itself is something that can be turned off via configuration option. There may be good reason to disable the default trace. Before disabling the default trace, please consider the following that can be captured via the default trace. I will use a query to demonstrate the events and categories that are configured for capture in the default trace.</p>
<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="coMULTI">/* events */</span>
<span class="kw1">SELECT</span> te.<span class="me1">name</span> <span class="kw1">AS</span> EventName
		,tca.<span class="me1">name</span> <span class="kw1">AS</span> CategoryName
		, <span class="kw1">CASE</span> tca.<span class="me1">type</span> <span class="kw1">WHEN</span> <span class="st0">'0'</span> <span class="kw1">THEN</span> <span class="st0">'Normal'</span>
				<span class="kw1">WHEN</span> <span class="st0">'1'</span> <span class="kw1">THEN</span> <span class="st0">'Connection'</span>
				<span class="kw1">WHEN</span> <span class="st0">'2'</span> <span class="kw1">THEN</span> <span class="st0">'ERROR'</span> <span class="kw1">END</span> <span class="kw1">AS</span> CategoryType
		, t.<span class="kw1">PATH</span> <span class="kw1">AS</span> TracePath
		, oa.<span class="me1">logical_operator</span>,oa.<span class="me1">comparison_operator</span>, oa.<span class="kw1">VALUE</span> <span class="kw1">AS</span> FilteredValue
	<span class="kw1">FROM</span> sys.<span class="me1">traces</span> t
		<span class="sy0">CROSS</span> APPLY <span class="br0">&#40;</span><span class="kw1">SELECT</span> <span class="kw1">DISTINCT</span> gei.<span class="me1">eventid</span> <span class="kw1">FROM</span> sys.<span class="kw4">FN_TRACE_GETEVENTINFO</span><span class="br0">&#40;</span>t.<span class="me1">id</span><span class="br0">&#41;</span> gei<span class="br0">&#41;</span> ca
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">trace_events</span> te
			<span class="kw1">ON</span> te.<span class="me1">trace_event_id</span> <span class="sy0">=</span> ca.<span class="me1">eventid</span>
		<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">trace_categories</span> tca
			<span class="kw1">ON</span> te.<span class="me1">category_id</span> <span class="sy0">=</span> tca.<span class="me1">category_id</span>
		<span class="sy0">OUTER</span> APPLY <span class="br0">&#40;</span><span class="kw1">SELECT</span> gfi.<span class="me1">columnid</span>,gfi.<span class="me1">logical_operator</span>,gfi.<span class="me1">comparison_operator</span>,gfi.<span class="kw1">VALUE</span> <span class="kw1">FROM</span> sys.<span class="kw4">FN_TRACE_GETFILTERINFO</span><span class="br0">&#40;</span>t.<span class="me1">id</span><span class="br0">&#41;</span> gfi<span class="br0">&#41;</span> oa
	<span class="kw1">WHERE</span> t.<span class="me1">is_default</span> <span class="sy0">=</span> <span class="nu0">1</span></pre></div></div></p>
<p>In this query, I have requested a few more data points than necessary to illustrate the point. That is to help illustrate an additional point that the default trace isn’t filtering out any data for these events. If the event fires (in this trace), it is recorded. Let’s divert right back to the events and categories for now. The results of that query will produce the following sample list of events for me on SQL Server 2014:</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events-968x1024.png" /></p>
<p>That is quite a range of events covered by this particular recording device. From changes to objects down to security related events and even errors and warnings. If somebody drops an object, the default trace can catch it. If one of the various DBCC statements is executed, it will be trapped in this trace.</p>
<p>There is one thing that is captured by this trace that is not overly obvious. In fact, it is rather annoying in how it is recorded in my opinion. Server configuration settings such as “cost threshold of parallelism” or the lesser utilized “user options” are not registered as an “Object:Alter” event but rather as an ErrorLog event. I wouldn’t call this type of “change” an error and don’t necessarily like seeing these registered with other legitimate errors. That said, it would be nice to see these logged differently (they are currently logged the same way with Extended Events). So, if somebody is dorking around with server configurations, it becomes a bit more convoluted to figure it out, but we can get there. Let’s see how that works:</p>
<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="co1">-- server configs Audited via Def Trace</span>
<span class="kw1">SELECT</span> 	T.<span class="me1">StartTime</span>
		, T.<span class="me1">SPID</span>
		, T.<span class="me1">LoginName</span>
		, T.<span class="me1">HostName</span>
		, T.<span class="me1">ApplicationName</span>
		, T.<span class="me1">DatabaseName</span>
		<span class="co1">--, ObjectName,sv.number AS ObjTypeVal, sv.name [ObjectType]</span>
		<span class="co1">--, T.TextData</span>
		, ConfigOption <span class="sy0">=</span> <span class="kw2">SUBSTRING</span><span class="br0">&#40;</span>T.<span class="me1">TextData</span>,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">''</span><span class="st0">''</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">+</span>1,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">' changed from '</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">-</span><span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">''</span><span class="st0">''</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">-</span>2<span class="br0">&#41;</span>
		, PrevValue <span class="sy0">=</span> <span class="kw2">SUBSTRING</span><span class="br0">&#40;</span>T.<span class="me1">TextData</span>,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'from '</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">+</span>5,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'to '</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">-</span><span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'from '</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">-</span>5<span class="br0">&#41;</span>
		, NewValue <span class="sy0">=</span> <span class="kw2">SUBSTRING</span><span class="br0">&#40;</span>T.<span class="me1">TextData</span>,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'to '</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">+</span>3,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'. Run'</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">-</span><span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'to '</span>,T.<span class="me1">TextData</span><span class="br0">&#41;</span><span class="sy0">-</span>3<span class="br0">&#41;</span>
		, EventName <span class="sy0">=</span> te.<span class="me1">name</span>
		, T.<span class="me1">EventClass</span>
	<span class="kw1">FROM</span> sys.<span class="kw4">FN_TRACE_GETTABLE</span><span class="br0">&#40;</span><span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">VARCHAR</span><span class="br0">&#40;</span>150<span class="br0">&#41;</span>, 
			<span class="br0">&#40;</span> <span class="kw1">SELECT</span> <span class="kw2">REVERSE</span><span class="br0">&#40;</span><span class="kw2">SUBSTRING</span><span class="br0">&#40;</span><span class="kw2">REVERSE</span><span class="br0">&#40;</span><span class="kw1">PATH</span><span class="br0">&#41;</span>,
					<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'<span class="es0">\'</span>,REVERSE(path)),256)) + '</span><span class="kw2">LOG</span>.<span class="me1">trc</span><span class="st0">'
				FROM    sys.traces
				WHERE   is_default = 1)), DEFAULT) AS T  
		INNER JOIN sys.trace_events AS te
			ON T.EventClass = te.trace_event_id
	WHERE T.EventClass = 22
		AND T.TextData LIKE '</span><span class="sy0">%</span>config<span class="sy0">%</span><span class="st0">'
	ORDER BY T.StartTime DESC;</span></pre></div></div></p>
<p>Looking at my system, I get the following sample results:</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs-1024x200.png" /></p>
<p>You can see there are plenty of settings that I have been playing with captured by the default trace. If you happen to have a junior DBA or maybe a cowboy DBA that loves to shoot from the hip and make changes, this will help you find all the necessary details to bring to that DBA for discussion.</p>
<p>The default trace comprises one third of the black box recorder. I have shown a quick use for the default trace and have also shown some of the various events that are captured from this trace. I recommend getting to know your default trace just a little bit better. You never know when you may need to resort to the flight recorder data held in the default trace. Being familiar with the default trace before you need to use it will help improve your comfort level when under the stress of trying to figure out what happened just before the server went belly up!</p>
<p>The post <a href="https://sqlsolutionsgroup.com/sql-black-box-recorder/">SQL Black Box Recorder</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Freakin&#8217; out on XE at the FreeCon</title>
		<link>https://sqlsolutionsgroup.com/freakin-out-on-xe/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 29 Sep 2015 18:02:07 +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[Extended Events]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2648</guid>

					<description><![CDATA[<p>Just a couple weeks ago I announced that SQL Solutions Group was getting ready to host a day of free training—a FREECON if you will—in Seattle as a prelude to the PASS Summit of 2015. You can read all about that here, with registration being here. I am hopeful to see the room filled with people looking [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/freakin-out-on-xe/">Freakin&#8217; out on XE at the FreeCon</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Just a couple weeks ago I announced that SQL Solutions Group was getting ready to host a day of free training—a FREECON if you will—in Seattle as a prelude to the PASS Summit of 2015. You can <a href="https://bit.ly/1Kl8m99">read all about that here</a>, with <a href="https://bit.ly/SSGSummit15">registration being here</a>.</p>
<p>I am hopeful to see the room filled with people looking to get some fantastic training. I also want to note that this training is not a part of the Summit, though I hope it is viewed as an effort to enhance the learning made available during the week of Summit and to give the attendees more options.</p>
<p>An option is only really any good if some sort of detail can be attained about the option. While I announced previously that the event was going to happen with a brief introduction into the the topics to be covered, one may be left wondering what really will be covered during the day.</p>
<p>With this post, I hope to help make the SSG FreeCon option a better option  by including a little detail into what it is that I will be presenting during my session on Extended Events.</p>
<h3>Extended Events</h3>
<p>This should come as a huge surprise given the <a href="https://bit.ly/XE60Days">60 Days of XEvents</a> series that I am currently publishing. While I am publishing a lot of information about XE in this series, this FreeCon session will cover the methodology that I, as a consultant, would use to troubleshoot various issues when a client seeks my help.</p>
<p>It is well known that there is a wealth of information within Extended Events. One can tap plenty of information about performance issues, errors, or general interest type stuff by setting up an XEvent Session and trapping some (hopefully) useful information.</p>
<p><a href="https://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap.jpg"><img loading="lazy" decoding="async" class="alignright wp-image-3014 size-medium" src="https://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap-300x206.jpg" alt="roadmap to XE understanding" width="300" height="206" /></a>During this session at the FreeCon, I want to help show how I would use Extended Events as a consultant to help find the pertinent information that will bring to light the problems the client is having.</p>
<p>How can I use XE as a consultant to perform a health check on your server? That information will be covered throughout this session.</p>
<p>How can I determine where precisely the backup failed (and when) and be able to procure more information to determine if it was caused by some other event on the network? This is the type of information included in the methodology that I plan to share.</p>
<p>Think of this session as a condensed road-map to XE Success. I look forward to seeing you there.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/freakin-out-on-xe/">Freakin&#8217; out on XE at the FreeCon</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>An Experiment with Deadlocks</title>
		<link>https://sqlsolutionsgroup.com/an-experiment-with-deadlocks/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 21 Jul 2015 12:22:15 +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[deadlocks]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2460</guid>

					<description><![CDATA[<p>Everything can be fixed with a query hint (*cough* directive), right? If a certain process is consistently causing deadlocks, a simple ROWLOCK hint can be added to prevent it, right? Well, for whatever reason, there seems to be a myth out there that when deadlocks come a-knocking, then just throw this little directive at it and [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/an-experiment-with-deadlocks/">An Experiment with Deadlocks</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Everything can be fixed with a query hint (*cough* directive), right? If a certain process is consistently causing deadlocks, a simple ROWLOCK hint can be added to prevent it, right?</p>
<p>Well, for whatever reason, there seems to be a myth out there that when deadlocks come a-knocking, then just throw this little directive at it and all will be well. Today, we get to test that and show what will continue to happen.</p>
<p>First, lets look at what the ROWLOCK actually means:</p>
<blockquote><p>Specifies that row locks are taken when page or table locks are ordinarily taken.</p></blockquote>
<p>This seems like a fabulous idea if the deadlocks are occurring against a table involving a massive update. Let’s take a look at a small update scenario involving just a handful of records.</p>
<p><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">Source code</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> tempdb;
GO
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'dbo.Test1'</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">Test1</span>;
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'dbo.Test2'</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">Test2</span>;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> dbo.<span class="me1">Test1</span> <span class="br0">&#40;</span> col1 <span class="kw1">INT</span> <span class="br0">&#41;</span>;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> dbo.<span class="me1">Test2</span> <span class="br0">&#40;</span> col2 <span class="kw1">INT</span> <span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">Test1</span>
	<span class="kw1">VALUES</span>	<span class="br0">&#40;</span> 1 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 2 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 3 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 4 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 5 <span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">Test2</span>
	<span class="kw1">VALUES</span>	<span class="br0">&#40;</span> 1 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 2 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 3 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 4 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 5 <span class="br0">&#41;</span>;
GO
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test1</span>
	<span class="kw1">SET</span>	col1 <span class="sy0">=</span> col1 <span class="sy0">*</span> 10
	<span class="kw1">WHERE</span> col1 <span class="sy0">=</span> <span class="nu0">3</span>;
&nbsp;
<span class="coMULTI">/* query window 2*/</span>
&nbsp;
<span class="kw1">USE</span> tempdb;
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test2</span>
	<span class="kw1">SET</span>	col2 <span class="sy0">=</span> col2 <span class="sy0">*</span> 20
	<span class="kw1">WHERE</span> col2 <span class="sy0">=</span> <span class="nu0">4</span>;
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test1</span>
	<span class="kw1">SET</span>	col1 <span class="sy0">=</span> col1 <span class="sy0">*</span> 20
	<span class="kw1">WHERE</span> col1 <span class="sy0">=</span> <span class="nu0">3</span>;
<span class="kw1">COMMIT</span> <span class="kw1">TRANSACTION</span>;
&nbsp;
<span class="coMULTI">/* back to the first query window*/</span>
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test2</span>
	<span class="kw1">SET</span>	col2 <span class="sy0">=</span> col2 <span class="sy0">*</span> 10
	<span class="kw1">WHERE</span> col2 <span class="sy0">=</span> <span class="nu0">4</span>;
<span class="kw1">COMMIT</span> <span class="kw1">TRANSACTION</span>;</pre></div></div></p>
<p>Looking at the code, we can see there are only five rows in each of the tables. In addition, an update will be performed to both col1 and col2 in each table for one specific row. So we are keeping this to a singleton type of update, and we are able to force a deadlock by using this setup. Not only do we see that a deadlock will occur consistently, we would see the following in the sys.dm_tran_locks DMV as well as in the deadlock graphs.</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/locks_held1-1024x521.png" /></p>
<p>In my environment, I used session 51 and 54 consistently for the deadlock repro. In each of the tests, each spid did obtain page locks as well as RID locks (row locks) that were waiting on each other in order to perform an Update. This is what we saw when I ran the setup without the ROWLOCK directive. What if I used the ROWLOCK directive (are you guessing already that there would be no change because the deadlock occurs on the lock held for the update that is waiting on the other update to complete?)? Let’s take a look at that too!</p>
<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">Source code</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">/* what about using rowlock hint? let's try it */</span>
<span class="kw1">USE</span> tempdb;
GO
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'dbo.Test1'</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">Test1</span>;
<span class="kw1">IF</span> <span class="kw2">OBJECT_ID</span><span class="br0">&#40;</span><span class="st0">'dbo.Test2'</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">Test2</span>;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> dbo.<span class="me1">Test1</span> <span class="br0">&#40;</span> col1 <span class="kw1">INT</span> <span class="br0">&#41;</span>;
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> dbo.<span class="me1">Test2</span> <span class="br0">&#40;</span> col2 <span class="kw1">INT</span> <span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">Test1</span>
	<span class="kw1">VALUES</span>	<span class="br0">&#40;</span> 1 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 2 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 3 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 4 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 5 <span class="br0">&#41;</span>;
<span class="kw1">INSERT</span> <span class="kw1">INTO</span> dbo.<span class="me1">Test2</span>
	<span class="kw1">VALUES</span>	<span class="br0">&#40;</span> 1 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 2 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 3 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 4 <span class="br0">&#41;</span>,
			<span class="br0">&#40;</span> 5 <span class="br0">&#41;</span>;
GO
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test1</span> <span class="kw1">WITH</span> <span class="br0">&#40;</span>ROWLOCK<span class="br0">&#41;</span>
	<span class="kw1">SET</span>	col1 <span class="sy0">=</span> col1 <span class="sy0">*</span> 10
	<span class="kw1">WHERE</span> col1 <span class="sy0">=</span> <span class="nu0">3</span>;
&nbsp;
<span class="coMULTI">/* query window 2*/</span>
&nbsp;
<span class="kw1">USE</span> tempdb;
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test2</span> <span class="kw1">WITH</span> <span class="br0">&#40;</span>ROWLOCK<span class="br0">&#41;</span>
	<span class="kw1">SET</span>	col2 <span class="sy0">=</span> col2 <span class="sy0">*</span> 20
	<span class="kw1">WHERE</span> col2 <span class="sy0">=</span> <span class="nu0">4</span>;
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test1</span> <span class="kw1">WITH</span> <span class="br0">&#40;</span>ROWLOCK<span class="br0">&#41;</span>
	<span class="kw1">SET</span>	col1 <span class="sy0">=</span> col1 <span class="sy0">*</span> 20
	<span class="kw1">WHERE</span> col1 <span class="sy0">=</span> <span class="nu0">3</span>;
<span class="kw1">COMMIT</span> <span class="kw1">TRANSACTION</span>;
&nbsp;
<span class="coMULTI">/* back to the first query window*/</span>
<span class="kw1">UPDATE</span> dbo.<span class="me1">Test2</span> <span class="kw1">WITH</span> <span class="br0">&#40;</span>ROWLOCK<span class="br0">&#41;</span>
	<span class="kw1">SET</span>	col2 <span class="sy0">=</span> col2 <span class="sy0">*</span> 10
	<span class="kw1">WHERE</span> col2 <span class="sy0">=</span> <span class="nu0">4</span>;
<span class="kw1">COMMIT</span> <span class="kw1">TRANSACTION</span>;</pre></div></div></p>
<p>The only change to this setup is that the ROWLOCK directive has been added to the update statements. Examining the sys.dm_tran_locks DMV reveals the same locks being held as was seen without the directive. This shouldn’t be too big of a surprise since the updates are against a single row.</p>
<p>In addition to the same locks being held, we continue to experience the same deadlock problem. Using an Extended Events session to trap deadlock information (similar to the article previously discussed), we can pull out some pretty good info. Let’s examine some of the deadlock data trapped by an XE session.</p>
<p><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">Source code</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="kw1">WITH</span>	cte	<span class="kw1">AS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/@name)[1]'</span>, <span class="st0">'varchar(50)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> event_name
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/@timestamp)[1]'</span>,
													<span class="st0">'datetime2'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> StartTime
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;duration&quot;]/value)[1]'</span>,
													<span class="st0">'bigint'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> duration
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;database_name&quot;]/value)[1]'</span>,
													<span class="st0">'sysname'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> DBName
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/action[@name=&quot;sql_text&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> sql_text
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/action[@name=&quot;nt_username&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(500)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> nt_username
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;mode&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(15)'</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">' ('</span>
							<span class="sy0">+</span> t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;mode&quot;]/text)[1]'</span>,
													<span class="st0">'varchar(50)'</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">')'</span> <span class="kw1">AS</span> mode
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;object_id&quot;]/value)[1]'</span>,
													<span class="st0">'integer'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> <span class="kw2">OBJECT_ID</span>
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;resource_description&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> resource_description
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;resource_owner_type&quot;]/text)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> resource_owner_type
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;resource_type&quot;]/text)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">' ('</span>
							<span class="sy0">+</span> t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;resource_type&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">')'</span> <span class="kw1">AS</span> resource_type
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/action[@name=&quot;server_principal_name&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> server_principal_name
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/action[@name=&quot;session_id&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> session_id
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/action[@name=&quot;client_pid&quot;]/value)[1]'</span>,
													<span class="st0">'integer'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> client_pid
							, t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/action[@name=&quot;client_app_name&quot;]/value)[1]'</span>,
													<span class="st0">'varchar(max)'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> client_app_name
							, t2.<span class="me1">event_data</span>
							,ROW_NUMBER<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">OVER</span> <span class="br0">&#40;</span><span class="kw1">ORDER</span> <span class="kw1">BY</span> t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/@timestamp)[1]'</span>,
													<span class="st0">'datetime2'</span><span class="br0">&#41;</span>
													,t2.<span class="me1">event_data</span>.<span class="kw1">VALUE</span><span class="br0">&#40;</span><span class="st0">'(event/@name)[1]'</span>, <span class="st0">'varchar(50)'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> Event_Seq
						<span class="kw1">FROM</span> sys.<span class="me1">fn_xe_file_target_read_file</span><span class="br0">&#40;</span><span class="st0">'C:<span class="es0">\D</span>atabase<span class="es0">\X</span>E<span class="es0">\D</span>eadlock*.xel'</span>,
																<span class="sy0">NULL</span>, <span class="sy0">NULL</span>, <span class="sy0">NULL</span><span class="br0">&#41;</span> t1
							<span class="sy0">CROSS</span> APPLY <span class="br0">&#40;</span> <span class="kw1">SELECT</span> <span class="kw1">CONVERT</span><span class="br0">&#40;</span>XML, t1.<span class="me1">event_data</span><span class="br0">&#41;</span>
										<span class="br0">&#41;</span> t2 <span class="br0">&#40;</span> event_data <span class="br0">&#41;</span>
				<span class="br0">&#41;</span>
	<span class="kw1">SELECT</span> c1.<span class="me1">event_name</span> <span class="kw1">AS</span> LockEvent, c2.<span class="me1">event_name</span> <span class="kw1">AS</span> GraphEvent
			, c1.<span class="me1">StartTime</span>
			, <span class="kw2">DATEADD</span><span class="br0">&#40;</span>MICROSECOND, c1.<span class="me1">duration</span>, <span class="kw1">CONVERT</span><span class="br0">&#40;</span>DATETIME2, <span class="br0">[</span>c1<span class="br0">]</span>.<span class="me1">StartTime</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> EndDate
			, c1.<span class="me1">duration</span>
			, c1.<span class="me1">DBName</span>
			, c1.<span class="me1">sql_text</span>
			, c1.<span class="me1">nt_username</span>
			, c1.<span class="me1">server_principal_name</span>
			, c1.<span class="me1">mode</span>
			, c1.<span class="kw2">OBJECT_ID</span>
			, c1.<span class="me1">resource_description</span>
			, c1.<span class="me1">resource_owner_type</span>
			, c1.<span class="me1">resource_type</span>
			, c1.<span class="me1">session_id</span>
			, c1.<span class="me1">client_pid</span>
			, c1.<span class="me1">client_app_name</span>
			, c1.<span class="me1">event_data</span>
			, graph.<span class="me1">query</span><span class="br0">&#40;</span><span class="st0">'.'</span><span class="br0">&#41;</span> <span class="kw1">AS</span> EventDeadlockGraph
		<span class="kw1">FROM</span> cte c1
			<span class="kw1">INNER</span> <span class="sy0">JOIN</span> cte c2
				<span class="kw1">ON</span> c1.<span class="me1">Event_Seq</span> <span class="sy0">=</span> c2.<span class="me1">Event_Seq</span> <span class="sy0">-</span> <span class="nu0">1</span>
			<span class="sy0">CROSS</span> APPLY c2.<span class="me1">event_data</span>.<span class="me1">nodes</span><span class="br0">&#40;</span><span class="st0">'(event/data[@name=&quot;xml_report&quot;]/value)[last()]/*'</span><span class="br0">&#41;</span>
				<span class="kw1">AS</span> deadlock <span class="br0">&#40;</span> graph <span class="br0">&#41;</span>
		<span class="kw1">WHERE</span> c1.<span class="me1">event_name</span> <span class="sy0">=</span> <span class="st0">'lock_deadlock'</span>
			<span class="sy0">AND</span> c2.<span class="me1">event_name</span> <span class="sy0">=</span> <span class="st0">'xml_deadlock_report'</span>
		<span class="kw1">ORDER</span> <span class="kw1">BY</span> c1.<span class="me1">StartTime</span>;</pre></div></div></p>
<p>The results from this query will show us the deadlock graph, the event data, as well as several other pieces of data already parsed from the session data for you. And looking at the session data, one can see that the sql_text from each of the queries will demonstrate both the ROWLOCK directive and the directive-free versions of the query. In this query you can also see that I did a little black magic to match up the two event types from the event session (lock_deadlock and xml_deadlock_report). Then I was able to join the two together to produce one row per deadlock event and to see the sql_text with the deadlock graph on one row. Otherwise, the sql_text does not produce with the deadlock_report event. I leave the rest of the query to the reader to discover and question.</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/xe_results-1024x141.png" /></p>
<p>From the EventDeadlockGraph column, we could click the cell and take a close look at the XML generated for the deadlock event. Further, if I choose to save the xml as an XDL file and then reopen it in SSMS, I can see the deadlock graphical report as shown in the following.</p>
<p><img decoding="async" src="https://jasonbrimhall.info/wp-content/uploads/2019/03/graphical_report-1024x348.png" /></p>
<p>We see that row locks are still in effect for the update coming from both sides. This further supports that the directive really is just a waste of time in trying to combat this type of deadlock. This is one of those cases where the best option would be to optimize the code and work things out without trying to take a shortcut.</p>
<h3>Wrapping Up</h3>
<p>Look to optimize the code instead of trying to take a shortcut. In addition, take a look at the deadlocks, the locks held, and the code to get a better understanding of what is truly happening.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/an-experiment-with-deadlocks/">An Experiment with Deadlocks</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Defaults In msdb Database</title>
		<link>https://sqlsolutionsgroup.com/defaults-in-msdb-database/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 15 Jul 2015 07:42:59 +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[msdb]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2443</guid>

					<description><![CDATA[<p>Today is a day to discuss defaults. It started with the day being TSQL Tuesday and having a topic of &#8220;Say No to Defaults.&#8221; You can read more about that from the invite &#8211; here. I already participated in the party but did also want to discuss msdb Database defaults a little bit more. That [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/defaults-in-msdb-database/">Defaults In msdb Database</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Today is a day to discuss defaults. It started with the day being TSQL Tuesday and having a topic of &#8220;Say No to Defaults.&#8221; You can read more about that from the invite &#8211; <a href="https://sqlbek.wordpress.com/2015/07/06/invitation-to-t-sql-tuesday-68-just-say-no-to-defaults/">here</a>. I already participated in the <img loading="lazy" decoding="async" class=" wp-image-2444 size-full alignleft" src="https://sqlsolutionsgroup.com/wp-content/uploads/2015/07/deadlydefaults.png" alt="deadlydefaults" width="276" height="183" />party but did also want to discuss msdb Database defaults a little bit more. That said, this article is not participating in the blog party. That would seem a bit silly.</p>
<p>While, this post is not a part of the party, the defaults to be discussed are fairly important. I have seen severe consequences due to these defaults being ignored and not changed. So today, I implore you to make some fundamental changes to your production servers with regards to various defaults.</p>
<h3>A Trio of msdb Defaults</h3>
<p>There aren’t really that many defaults within the msdb database that must be changed, are there? I mean, seriously, beyond the defaults that are available to every database, what could possibly be unique to this database that could have a severe consequence?</p>
<p>I am so glad you asked!</p>
<p>The defaults in the msdb database are more about what is missing than what is actually there. By default, this database is missing quite a few things that could be deemed critical to your environment.</p>
<h3>Let’s start with an easy one – Indexes</h3>
<p>There are a few out there that may disagree, but the proof really is in the effect on performance for backup jobs and such. I have three indexes I like to put on every instance. I have seen the implementation of these indexes aid in improved job times as well as aid in reduced time to “clean” up the database.</p>
<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">Source code</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="coMULTI">/* Number 1 */</span>
<span class="coMULTI">/* msdb maintenance activity related indexes */</span>
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> IX_maintplan_taskdetailid <span class="kw1">ON</span> <span class="br0">[</span>msdb<span class="br0">]</span>.<span class="br0">[</span>dbo<span class="br0">]</span>.<span class="br0">[</span>sysmaintplan_logdetail<span class="br0">]</span>
<span class="br0">&#40;</span><span class="br0">[</span>task_detail_id<span class="br0">]</span><span class="br0">&#41;</span>
<span class="kw1">WITH</span> <span class="br0">&#40;</span><span class="kw1">FILLFACTOR</span> <span class="sy0">=</span> 90<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> IX_backupset_type <span class="kw1">ON</span> msdb.<span class="me1">dbo</span>.<span class="me1">backupset</span>
<span class="br0">&#40;</span><span class="br0">[</span>type<span class="br0">]</span>,<span class="br0">[</span>backup_finish_date<span class="br0">]</span><span class="br0">&#41;</span>
<span class="sy0">IN</span>CLUDE <span class="br0">&#40;</span><span class="br0">[</span>media_set_id<span class="br0">]</span>, <span class="br0">[</span>database_name<span class="br0">]</span><span class="br0">&#41;</span>
<span class="kw1">WITH</span> <span class="br0">&#40;</span><span class="kw1">FILLFACTOR</span> <span class="sy0">=</span> 90<span class="br0">&#41;</span>;
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">INDEX</span> IX_jobactivity_jobid <span class="kw1">ON</span> <span class="br0">[</span>msdb<span class="br0">]</span>.<span class="br0">[</span>dbo<span class="br0">]</span>.<span class="br0">[</span>sysjobactivity<span class="br0">]</span>
<span class="br0">&#40;</span><span class="br0">[</span>job_id<span class="br0">]</span><span class="br0">&#41;</span>
<span class="sy0">IN</span>CLUDE <span class="br0">&#40;</span><span class="br0">[</span>session_id<span class="br0">]</span><span class="br0">&#41;</span>
<span class="kw1">WITH</span> <span class="br0">&#40;</span><span class="kw1">FILLFACTOR</span> <span class="sy0">=</span> 90<span class="br0">&#41;</span>;</pre></div></div></p>
<p>Easy enough. These indexes are very straight forward and pretty small in the grand scheme of things. But if the index can help improve performance by a factor of 10, then I am in favor of them (and I have seen that performance gain).</p>
<p>Now that we have some supporting indexes to help a bit with performance, we should take a look at the next item. This one can help with job performance as well as help with keeping the msdb database nice and trim.</p>
<h3>Data Pruning</h3>
<p>I have walked into client instances that had backup history dating all the way back to 2005 and included two-three full backups a day per database with quarter-hourly log backups. Oh and this was for an instance containing well north of 200 databases. Can you say sluggish backups and sluggish msdb overall?</p>
<p>The fix is very easy! Not only do I recommend pruning the backup history, but also the job history, mail history and maintenance plan history (eew – if you use those things). Think about it – do you really need to know that Job XYZ ran successfully in 2006 and only took 15 seconds? This is 2015 and that kind of data is probably not pertinent at this point.</p>
<p>The pruning of this data is not enabled by default! You have to configure this for each of the servers under your purview. Luckily, this is easy to do!</p>
<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">Source code</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="coMULTI">/* NUMBER 2 */</span>
<span class="coMULTI">/****** Object:  Job [DBA - Clean msdb Historical data]    Script Date: 03/06/2013 17:40:02 ******/</span>
<span class="kw1">BEGIN</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">DECLARE</span> @ReturnCode <span class="kw1">INT</span>;
<span class="kw1">SELECT</span> @ReturnCode <span class="sy0">=</span> <span class="nu0">0</span>;
<span class="coMULTI">/****** Object:  JobCategory [DBA Maintenance]]    Script Date: 03/06/2013 17:40:03 ******/</span>
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">syscategories</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Maintenance'</span>
						<span class="sy0">AND</span> category_class <span class="sy0">=</span> 1 <span class="br0">&#41;</span>
	<span class="kw1">BEGIN</span>
		<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_CATEGORY</span> @<span class="kw1">CLASS</span> <span class="sy0">=</span> N<span class="st0">'JOB'</span>,
			@type <span class="sy0">=</span> N<span class="st0">'LOCAL'</span>, @name <span class="sy0">=</span> N<span class="st0">'DBA Maintenance'</span>;
		<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
				<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
			<span class="br0">&#41;</span>
			<span class="kw1">GOTO</span> QuitWithRollback;
&nbsp;
	<span class="kw1">END</span>;
&nbsp;
<span class="kw1">DECLARE</span> @jobId <span class="kw1">BINARY</span><span class="br0">&#40;</span>16<span class="br0">&#41;</span>;
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOB</span> @job_name <span class="sy0">=</span> N<span class="st0">'DBA - Clean msdb Historical data'</span>,
	@enabled <span class="sy0">=</span> <span class="nu0">1</span>, @notify_level_eventlog <span class="sy0">=</span> <span class="nu0">0</span>, @notify_level_email <span class="sy0">=</span> <span class="nu0">0</span>,
	@notify_level_netsend <span class="sy0">=</span> <span class="nu0">0</span>, @notify_level_page <span class="sy0">=</span> <span class="nu0">0</span>, @delete_level <span class="sy0">=</span> <span class="nu0">0</span>,
	@description <span class="sy0">=</span> N<span class="st0">'No description available.'</span>,
	@category_name <span class="sy0">=</span> N<span class="st0">'DBA Maintenance'</span>, @owner_login_name <span class="sy0">=</span> N<span class="st0">'sa'</span>,
	@job_id <span class="sy0">=</span> @jobId <span class="kw1">OUTPUT</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="coMULTI">/****** Object:  Step [Purge Backup History]    Script Date: 03/06/2013 17:40:03 ******/</span>
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOBSTEP</span> @job_id <span class="sy0">=</span> @jobId,
	@step_name <span class="sy0">=</span> N<span class="st0">'Purge Backup History'</span>, @step_id <span class="sy0">=</span> <span class="nu0">1</span>,
	@cmdexec_success_code <span class="sy0">=</span> <span class="nu0">0</span>, @on_success_action <span class="sy0">=</span> <span class="nu0">3</span>, @on_success_step_id <span class="sy0">=</span> <span class="nu0">0</span>,
	@on_fail_action <span class="sy0">=</span> <span class="nu0">2</span>, @on_fail_step_id <span class="sy0">=</span> <span class="nu0">0</span>, @retry_attempts <span class="sy0">=</span> <span class="nu0">0</span>,
	@retry_interval <span class="sy0">=</span> <span class="nu0">0</span>, @os_run_priority <span class="sy0">=</span> <span class="nu0">0</span>, @subsystem <span class="sy0">=</span> N<span class="st0">'TSQL'</span>,
	@command <span class="sy0">=</span> N<span class="st0">'/* Cleanup old backup history */
DECLARE @BackupHistoryOlderThan DATETIME
Set @BackupHistoryOlderThan = DATEADD(d, -90, GETDATE())
EXECUTE msdb.dbo.sp_delete_backuphistory @BackupHistoryOlderThan
&nbsp;
'</span>, @database_name <span class="sy0">=</span> N<span class="st0">'msdb'</span>, @flags <span class="sy0">=</span> <span class="nu0">4</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="coMULTI">/****** Object:  Step [Purge MaintPlan Log Data]    Script Date: 03/06/2013 17:40:04 ******/</span>
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOBSTEP</span> @job_id <span class="sy0">=</span> @jobId,
	@step_name <span class="sy0">=</span> N<span class="st0">'Purge MaintPlan Log Data'</span>, @step_id <span class="sy0">=</span> <span class="nu0">2</span>,
	@cmdexec_success_code <span class="sy0">=</span> <span class="nu0">0</span>, @on_success_action <span class="sy0">=</span> <span class="nu0">3</span>, @on_success_step_id <span class="sy0">=</span> <span class="nu0">0</span>,
	@on_fail_action <span class="sy0">=</span> <span class="nu0">2</span>, @on_fail_step_id <span class="sy0">=</span> <span class="nu0">0</span>, @retry_attempts <span class="sy0">=</span> <span class="nu0">0</span>,
	@retry_interval <span class="sy0">=</span> <span class="nu0">0</span>, @os_run_priority <span class="sy0">=</span> <span class="nu0">0</span>, @subsystem <span class="sy0">=</span> N<span class="st0">'TSQL'</span>,
	@command <span class="sy0">=</span> N<span class="st0">'Declare @OldDate DateTime
Set @OldDate = GETDATE() - 14;
&nbsp;
Execute msdb.dbo.sp_maintplan_delete_log @oldest_time = @OldDate'</span>,
	@database_name <span class="sy0">=</span> N<span class="st0">'msdb'</span>, @flags <span class="sy0">=</span> <span class="nu0">4</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="coMULTI">/****** Object:  Step [Purge Mail History]    Script Date: 03/06/2013 17:40:04 ******/</span>
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOBSTEP</span> @job_id <span class="sy0">=</span> @jobId,
	@step_name <span class="sy0">=</span> N<span class="st0">'Purge Mail History'</span>, @step_id <span class="sy0">=</span> <span class="nu0">3</span>, @cmdexec_success_code <span class="sy0">=</span> <span class="nu0">0</span>,
	@on_success_action <span class="sy0">=</span> <span class="nu0">3</span>, @on_success_step_id <span class="sy0">=</span> <span class="nu0">0</span>, @on_fail_action <span class="sy0">=</span> <span class="nu0">2</span>,
	@on_fail_step_id <span class="sy0">=</span> <span class="nu0">0</span>, @retry_attempts <span class="sy0">=</span> <span class="nu0">0</span>, @retry_interval <span class="sy0">=</span> <span class="nu0">0</span>,
	@os_run_priority <span class="sy0">=</span> <span class="nu0">0</span>, @subsystem <span class="sy0">=</span> N<span class="st0">'TSQL'</span>,
	@command <span class="sy0">=</span> N<span class="st0">'/* Cleanup old mail items */
DECLARE @MailItemHistoryOlderThan DATETIME
Set @MailItemHistoryOlderThan = DATEADD(d, -14, GETDATE())
EXECUTE msdb.dbo.sysmail_delete_mailitems_sp @sent_before = @MailItemHistoryOlderThan
&nbsp;
'</span>, @database_name <span class="sy0">=</span> N<span class="st0">'master'</span>, @flags <span class="sy0">=</span> <span class="nu0">0</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="coMULTI">/****** Object:  Step [Purge Job History]    Script Date: 03/06/2013 17:40:04 ******/</span>
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOBSTEP</span> @job_id <span class="sy0">=</span> @jobId,
	@step_name <span class="sy0">=</span> N<span class="st0">'Purge Job History'</span>, @step_id <span class="sy0">=</span> <span class="nu0">4</span>, @cmdexec_success_code <span class="sy0">=</span> <span class="nu0">0</span>,
	@on_success_action <span class="sy0">=</span> <span class="nu0">1</span>, @on_success_step_id <span class="sy0">=</span> <span class="nu0">0</span>, @on_fail_action <span class="sy0">=</span> <span class="nu0">2</span>,
	@on_fail_step_id <span class="sy0">=</span> <span class="nu0">0</span>, @retry_attempts <span class="sy0">=</span> <span class="nu0">0</span>, @retry_interval <span class="sy0">=</span> <span class="nu0">0</span>,
	@os_run_priority <span class="sy0">=</span> <span class="nu0">0</span>, @subsystem <span class="sy0">=</span> N<span class="st0">'TSQL'</span>,
	@command <span class="sy0">=</span> N<span class="st0">'/*Cleanup of Old Job History*/
Declare @JobHistoryOlderThan DATETIME
Set @JobHistoryOlderThan = DATEADD(d, -14, GETDATE())
EXECUTE msdb.dbo.sp_purge_jobhistory @oldest_date = @JobHistoryOlderThan'</span>,
	@database_name <span class="sy0">=</span> N<span class="st0">'master'</span>, @flags <span class="sy0">=</span> <span class="nu0">0</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_UPDATE_JOB</span> @job_id <span class="sy0">=</span> @jobId, @start_step_id <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOBSCHEDULE</span> @job_id <span class="sy0">=</span> @jobId,
	@name <span class="sy0">=</span> N<span class="st0">'Daily'</span>, @enabled <span class="sy0">=</span> 1, @freq_type <span class="sy0">=</span> 4, @freq_interval <span class="sy0">=</span> 1,
	@freq_subday_type <span class="sy0">=</span> 1, @freq_subday_interval <span class="sy0">=</span> 0,
	@freq_relative_interval <span class="sy0">=</span> 0, @freq_recurrence_factor <span class="sy0">=</span> 0,
	@active_start_date <span class="sy0">=</span> 20120831, @active_end_date <span class="sy0">=</span> 99991231,
	@active_start_time <span class="sy0">=</span> 0, @active_end_time <span class="sy0">=</span> <span class="nu0">235959</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="kw1">EXEC</span> @ReturnCode <span class="sy0">=</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_JOBSERVER</span> @job_id <span class="sy0">=</span> @jobId,
	@server_name <span class="sy0">=</span> N<span class="st0">'(local)'</span>;
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@ERROR</span> <span class="sy0">&lt;&gt;</span> 0
		<span class="sy0">OR</span> @ReturnCode <span class="sy0">&lt;&gt;</span> 0
	<span class="br0">&#41;</span>
	<span class="kw1">GOTO</span> QuitWithRollback;
<span class="kw1">COMMIT</span> <span class="kw1">TRANSACTION</span>;
<span class="kw1">GOTO</span> EndSave;
QuitWithRollback:
<span class="kw1">IF</span> <span class="br0">&#40;</span> <span class="kw2">@@TRANCOUNT</span> <span class="sy0">&gt;</span> 0 <span class="br0">&#41;</span>
	<span class="kw1">ROLLBACK</span> <span class="kw1">TRANSACTION</span>;
EndSave:
&nbsp;
GO</pre></div></div></p>
<p>If you use this code sample, be sure to adjust the number of days shown in the retention to match your specific needs.</p>
<p>Now we have addressed a couple of defaults in msdb that can impact your performance. We are tidying up the database and in a much happier state these days. There is one more default, though, that is really critical to your data’s well being. This one is set within the msdb database but it really is for all of your databases!</p>
<h3>Configuring Alerts!</h3>
<p>I’m not talking about just any alerts. There are some very specific alerts that really should be configured. These are the alerts that can help you intervene to minimize corruption.</p>
<p>If you haven’t faced a problem with corruption – you will. It is only a matter of time. Corruption happens. When it happens, the earlier one can intervene, usually the better the outcome. Every minute counts, so why not try to reduce that time as much as possible?</p>
<p>This one is not terribly difficult to implement. I happen to have a query ready to go for that as well. All that needs to be done is a minor adjustment to the alert email address:</p>
<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">Source code</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="coMULTI">/* Number 3 */</span>
<span class="kw1">USE</span> <span class="br0">[</span>msdb<span class="br0">]</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
				<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
				<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 823'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_DELETE_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 823'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 823'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 823'</span>,
		@message_id <span class="sy0">=</span> <span class="nu0">823</span>, @severity <span class="sy0">=</span> <span class="nu0">0</span>, @enabled <span class="sy0">=</span> <span class="nu0">1</span>,
		@delay_between_responses <span class="sy0">=</span> <span class="nu0">600</span>, @include_event_description_in <span class="sy0">=</span> <span class="nu0">1</span>,
		@notification_message <span class="sy0">=</span> N<span class="st0">'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.'</span>,
		@category_name <span class="sy0">=</span> N<span class="st0">'[Uncategorized]'</span>,
		@job_id <span class="sy0">=</span> N<span class="st0">'00000000-0000-0000-0000-000000000000'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
				<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
				<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 824'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_DELETE_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 824'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 824'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 824'</span>,
		@message_id <span class="sy0">=</span> <span class="nu0">824</span>, @severity <span class="sy0">=</span> <span class="nu0">0</span>, @enabled <span class="sy0">=</span> <span class="nu0">1</span>,
		@delay_between_responses <span class="sy0">=</span> <span class="nu0">600</span>, @include_event_description_in <span class="sy0">=</span> <span class="nu0">1</span>,
		@notification_message <span class="sy0">=</span> N<span class="st0">'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.'</span>,
		@category_name <span class="sy0">=</span> N<span class="st0">'[Uncategorized]'</span>,
		@job_id <span class="sy0">=</span> N<span class="st0">'00000000-0000-0000-0000-000000000000'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
				<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
				<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 825'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_DELETE_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 825'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 825'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 825'</span>,
		@message_id <span class="sy0">=</span> <span class="nu0">825</span>, @severity <span class="sy0">=</span> <span class="nu0">0</span>, @enabled <span class="sy0">=</span> <span class="nu0">1</span>,
		@delay_between_responses <span class="sy0">=</span> <span class="nu0">600</span>, @include_event_description_in <span class="sy0">=</span> <span class="nu0">1</span>,
		@notification_message <span class="sy0">=</span> N<span class="st0">'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.'</span>,
		@category_name <span class="sy0">=</span> N<span class="st0">'[Uncategorized]'</span>,
		@job_id <span class="sy0">=</span> N<span class="st0">'00000000-0000-0000-0000-000000000000'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
				<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
				<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 829'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_DELETE_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 829'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 829'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 829'</span>,
		@message_id <span class="sy0">=</span> <span class="nu0">829</span>, @severity <span class="sy0">=</span> <span class="nu0">0</span>, @enabled <span class="sy0">=</span> <span class="nu0">1</span>,
		@delay_between_responses <span class="sy0">=</span> <span class="nu0">600</span>, @include_event_description_in <span class="sy0">=</span> <span class="nu0">1</span>,
		@notification_message <span class="sy0">=</span> N<span class="st0">'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.'</span>,
		@category_name <span class="sy0">=</span> N<span class="st0">'[Uncategorized]'</span>,
		@job_id <span class="sy0">=</span> N<span class="st0">'00000000-0000-0000-0000-000000000000'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
				<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
				<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 832'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_DELETE_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 832'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysalerts</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 832'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_ALERT</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 832'</span>,
		@message_id <span class="sy0">=</span> <span class="nu0">832</span>, @severity <span class="sy0">=</span> <span class="nu0">0</span>, @enabled <span class="sy0">=</span> <span class="nu0">1</span>,
		@delay_between_responses <span class="sy0">=</span> <span class="nu0">600</span>, @include_event_description_in <span class="sy0">=</span> <span class="nu0">1</span>,
		@notification_message <span class="sy0">=</span> N<span class="st0">'Page memory error detected. This could be a sign of impending memory failure. Forward this ticket to the primary DBA for this account for followup.'</span>,
		@category_name <span class="sy0">=</span> N<span class="st0">'[Uncategorized]'</span>,
		@job_id <span class="sy0">=</span> N<span class="st0">'00000000-0000-0000-0000-000000000000'</span>;
GO
&nbsp;
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span> <span class="kw1">SELECT</span> name
					<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysoperators</span>
					<span class="kw1">WHERE</span> name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span> <span class="br0">&#41;</span>
	<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_OPERATOR</span> @name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span>, @enabled <span class="sy0">=</span> <span class="nu0">1</span>,
		@weekday_pager_start_time <span class="sy0">=</span> <span class="nu0">90000</span>, @weekday_pager_end_time <span class="sy0">=</span> <span class="nu0">180000</span>,
		@saturday_pager_start_time <span class="sy0">=</span> <span class="nu0">90000</span>, @saturday_pager_end_time <span class="sy0">=</span> <span class="nu0">180000</span>,
		@sunday_pager_start_time <span class="sy0">=</span> <span class="nu0">90000</span>, @sunday_pager_end_time <span class="sy0">=</span> <span class="nu0">180000</span>,
		@pager_days <span class="sy0">=</span> <span class="nu0">0</span>, @email_address <span class="sy0">=</span> N<span class="st0">'su*****@*BA.com'</span>,
		@category_name <span class="sy0">=</span> N<span class="st0">'[Uncategorized]'</span>;
GO
<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_NOTIFICATION</span> @alert_name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 823'</span>,
	@operator_name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span>, @notification_method <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_NOTIFICATION</span> @alert_name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 824'</span>,
	@operator_name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span>, @notification_method <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_NOTIFICATION</span> @alert_name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 825'</span>,
	@operator_name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span>, @notification_method <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_NOTIFICATION</span> @alert_name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 829'</span>,
	@operator_name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span>, @notification_method <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="kw1">EXEC</span> msdb.<span class="me1">dbo</span>.<span class="kw3">SP_ADD_NOTIFICATION</span> @alert_name <span class="sy0">=</span> N<span class="st0">'DBA Alert: Message Id: 832'</span>,
	@operator_name <span class="sy0">=</span> N<span class="st0">'DBA Support'</span>, @notification_method <span class="sy0">=</span> <span class="nu0">1</span>;
GO</pre></div></div></p>
<h2>Wrap</h2>
<p>Wow! Now there are three quick defaults that must be changed on every server. These defaults will help improve performance as well as help you stay on top of things when they start to go south (corruption). With timely notifications, and better performance, your servers will be happier, healthier, and longer lasting.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/defaults-in-msdb-database/">Defaults In msdb Database</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Upgrading From SQL Server Profiler</title>
		<link>https://sqlsolutionsgroup.com/upgrading-from-sql-server-profiler/</link>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 22 Apr 2015 14:38:46 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<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[Extended Events]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://sqlsolutionsgroup.com/?p=2223</guid>

					<description><![CDATA[<p>You may recall an article I had written a couple months back describing how to use Extended Events to perform your SQL Server Profiler duties. If not, you can read all about it here. In that article, I showed one common use-case for SQL Server Profiler and how to achieve the same result via Extended [&#8230;]</p>
<p>The post <a href="https://sqlsolutionsgroup.com/upgrading-from-sql-server-profiler/">Upgrading From SQL Server Profiler</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>You may recall an article I had written a couple months back describing how to use <a href="https://bit.ly/2ELiQaf">Extended Events to perform your SQL Server Profiler duties</a>. If not, you can read all about it <a href="https://bit.ly/2ELiQaf">here</a>.</p>
<p><img decoding="async" class="alignnone" src="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="sql server profiler" width="350" /></p>
<p>In that article, I showed one common use-case for SQL Server Profiler and how to achieve the same result via Extended Events. What I didn&#8217;t show in that article was how to correlate all of your favorite trace/profiler options into the shiny new XE equivalents. Is there even a way to do that?</p>
<p>As luck would have it, there is a means to correlate trace/profiler events to Extended Event events (yeah that sounds weird).  With the release of SQL Server 2012, Microsoft introduced a couple of catalog views to help with this correlation effort. Those views have a pretty straightforward naming convention. For example, one of the views is named sys.trace_xe_event_map while the other is sys.trace_xe_action_map. For this article, I will be focusing on the former.</p>
<h3>Making the Upgrade</h3>
<p>When looking to finally make the upgrade away from trace/profiler, a big key is to figure out if your favorite trace events are even an option at the next level. I have talked about <a href="https://bit.ly/SSGTrifecta">finding events in XE</a> in previous articles by trying to search for a specific topic that might apply to your current condition.</p>
<p>But if you are already familiar with specific trace events, you may just want/need to know what the new name is in XE. This is where those catalog views come into play. And in support of that, here is a query that can help in that upgrade effort:</p>
<p><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">Source code</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="kw1">SELECT</span> te.<span class="me1">trace_event_id</span>,tc.<span class="me1">name</span> <span class="kw1">AS</span> CategoryName
	, <span class="kw1">CASE</span> tc.<span class="me1">type</span>
		<span class="kw1">WHEN</span> 0 <span class="kw1">THEN</span> <span class="st0">'Normal'</span>
		<span class="kw1">WHEN</span> 1 <span class="kw1">THEN</span> <span class="st0">'Connection'</span>
		<span class="kw1">WHEN</span> 2 <span class="kw1">THEN</span> <span class="st0">'ERROR'</span>
		<span class="kw1">END</span> <span class="kw1">AS</span> TraceEventType
	,te.<span class="me1">name</span> <span class="kw1">AS</span> TraceEventName
	, xem.<span class="me1">package_name</span>, xem.<span class="me1">xe_event_name</span>
<span class="kw1">FROM</span> sys.<span class="me1">trace_xe_event_map</span> xem
	<span class="kw1">RIGHT</span> <span class="sy0">OUTER</span> <span class="sy0">JOIN</span> sys.<span class="me1">trace_events</span> te
		<span class="kw1">ON</span> te.<span class="me1">trace_event_id</span> <span class="sy0">=</span> xem.<span class="me1">trace_event_id</span>
	<span class="kw1">INNER</span> <span class="sy0">JOIN</span> sys.<span class="me1">trace_categories</span> tc
		<span class="kw1">ON</span> te.<span class="me1">category_id</span> <span class="sy0">=</span> tc.<span class="me1">category_id</span>
<span class="kw1">ORDER</span> <span class="kw1">BY</span> tc.<span class="me1">category_id</span>,te.<span class="me1">trace_event_id</span> <span class="kw1">ASC</span>;</pre></div></div></p>
<p>Looking through the results, one would notice that not every trace event maps to an Extended Event event. The events that don’t map, in general, deal with audits (which is actually driven by Extended Events).</p>
<p>This is a really good start to getting you on your way to that much needed upgrade away from profiler/trace. What if there are several traces that are already in use or scripted for various reasons in the environment?</p>
<h3>Decision Time</h3>
<p>If you happen to have traces that are already deployed in the environment or in script form, it can be a bit of a tedious pain to convert those to Extended Events. Do you manually recreate the traces as XE sessions? Do you abandon the upgrade due to the effort and annoyance it will create? Or do you find some automated means of performing the conversion?</p>
<p>Of those three options, only two are valid options. Those options involve performing the conversion of the traces to XE sessions. There are pros and cons for each. You may opt to take your time and learn more about Extended Events by performing the manual upgrade, or you may choose to save time by using an automated routine.</p>
<p>Should you decide to try the automated routine, there is one already out and available to help you on your way. Jonathan Kehayias wrote the script and you can download it <a href="https://www.sqlskills.com/blogs/jonathan/converting-sql-trace-to-extended-events-in-sql-server-2012/">here</a>.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/upgrading-from-sql-server-profiler/">Upgrading From SQL Server Profiler</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
