<?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>SQL Server with Mr. Denny &#187; Execution Plans</title>
	<atom:link href="http://itknowledgeexchange.techtarget.com/sql-server/tag/execution-plans/feed/" rel="self" type="application/rss+xml" />
	<link>http://itknowledgeexchange.techtarget.com/sql-server</link>
	<description></description>
	<lastBuildDate>Wed, 19 Jun 2013 19:39:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Extra Bytes Per Row With AlwaysOn Availability Groups</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/extra-bytes-per-row-with-alwayson-availability-groups/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/extra-bytes-per-row-with-alwayson-availability-groups/#comments</comments>
		<pubDate>Tue, 28 May 2013 16:27:36 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Execution Plans]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[Index Performance]]></category>
		<category><![CDATA[Index Seek]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/?p=2676</guid>
		<description><![CDATA[One of things to keep in mind with SQL Server 2012 AlwaysOn Availability Groups is that when the availability group has readable secondary replicas any rows that are changed will have an additional 14 bytes added to each row.  These 14 bytes are used by the readable secondary to handle the read committed snapshot isolation [...]]]></description>
				<content:encoded><![CDATA[<p>One of things to keep in mind with SQL Server 2012 AlwaysOn Availability Groups is that when the availability group has readable secondary replicas any rows that are changed will have an additional 14 bytes added to each row.  These 14 bytes are used by the readable secondary to handle the read committed snapshot isolation level (RCSI) so that the readable secondary replicas work correctly.</p>
<p>To look at what’s going on lets create a sample new table in a table and take a peak at the data.  To setup this test we create a new database and setup that database for use with AlwaysOn Availability Groups.  The availability group is setup with no readable secondary replicas.</p>
<blockquote><p>create table MyTest (c1 int identity(1,1),<br />
c2 int,<br />
c3 varchar(100))<br />
GO<br />
insert into MyTest<br />
(c2, c3)<br />
values<br />
(1, &#8216;test&#8217;)<br />
GO 400</p></blockquote>
<p>This creates a new table in the database with 400 rows in it.  Looking at the output from DBCC IND we can see that this table takes up 2 data pages with a root page (this will become important later on).</p>
<p>Looking at the data for the first data page we can see the following information.</p>
<blockquote><p>Slot 0 Offset 0&#215;60 Length 23</p>
<p>Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 23<br />
Memory Dump @0x000000003CACA060</p>
<p>0000000000000000:   30000c00 01000000 01000000 03000001 00170074  0&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;t<br />
0000000000000014:   657374                                        est</p>
<p>Slot 0 Column 1 Offset 0&#215;4 Length 4 Length (physical) 4</p>
<p>c1 = 1</p>
<p>Slot 0 Column 2 Offset 0&#215;8 Length 4 Length (physical) 4</p>
<p>c2 = 1</p>
<p>Slot 0 Column 3 Offset 0&#215;13 Length 4 Length (physical) 4</p>
<p>c3 = test</p>
<p>Slot 0 Offset 0&#215;0 Length 0 Length (physical) 0</p>
<p>KeyHashValue = (8194443284a0)</p></blockquote>
<p>When we update this row changing the value of c2 to equal 2 nothing really changes which we can see from DBCC PAGE again.</p>
<blockquote><p>Slot 0 Offset 0&#215;60 Length 23</p>
<p>Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 23<br />
Memory Dump @0x000000003EECA060</p>
<p>0000000000000000:   30000c00 01000000 02000000 03000001 00170074  0&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;t<br />
0000000000000014:   657374                                        est</p>
<p>Slot 0 Column 1 Offset 0&#215;4 Length 4 Length (physical) 4</p>
<p>c1 = 1</p>
<p>Slot 0 Column 2 Offset 0&#215;8 Length 4 Length (physical) 4</p>
<p>c2 = 2</p>
<p>Slot 0 Column 3 Offset 0&#215;13 Length 4 Length (physical) 4</p>
<p>c3 = test</p>
<p>Slot 0 Offset 0&#215;0 Length 0 Length (physical) 0</p>
<p>KeyHashValue = (8194443284a0)</p></blockquote>
<p>Next I’ve changed the settings for the availability group to support readable secondary replicas.  Once that change has been made we change the value of c2 for the same row to equal the value of 3.  Again we can look at this with DBCC PAGE.</p>
<blockquote><p>Slot 0 Offset 0x1d4e Length 37</p>
<p>Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS VERSIONING_INFO<br />
Record Size = 37<br />
Memory Dump @0x000000003AEEBD4E</p>
<p>0000000000000000:   70000c00 01000000 03000000 03000001 00170074  p&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;t<br />
0000000000000014:   65737400 00000000 0000000f 06000000 00        est&#8230;&#8230;&#8230;&#8230;..</p>
<p>Version Information =<br />
Transaction Timestamp: 1551<br />
Version Pointer: Null</p>
<p>Slot 0 Column 1 Offset 0&#215;4 Length 4 Length (physical) 4</p>
<p>c1 = 1</p>
<p>Slot 0 Column 2 Offset 0&#215;8 Length 4 Length (physical) 4</p>
<p>c2 = 3</p>
<p>Slot 0 Column 3 Offset 0&#215;13 Length 4 Length (physical) 4</p>
<p>c3 = test</p>
<p>Slot 0 Offset 0&#215;0 Length 0 Length (physical) 0</p>
<p>KeyHashValue = (8194443284a0)</p></blockquote>
<p>Looking at these two outputs from DBCC PAGE we can see a couple of differences.  First we see an additional value in the “Record Attributes” field which adds in VERSIONING_INFO to the value.  We also see that the record size has changed from 32 to 37.  Additionally we see that the Version Information has been added.</p>
<p>Looking at the DBCC PAGE output on one of the replicas for the same page as before we see some different information.</p>
<blockquote><p>Slot 0 Offset 0x1d4e Length 37</p>
<p>Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS VERSIONING_INFO<br />
Record Size = 37<br />
Memory Dump @0x000000003893BD4E</p>
<p>0000000000000000:   70000c00 01000000 03000000 03000001 00170074  p&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;t<br />
0000000000000014:   65737440 01000001 0000000f 06000000 00        est@&#8230;&#8230;&#8230;&#8230;.</p>
<p>Version Information =<br />
Transaction Timestamp: 1551<br />
Version Pointer: (file 1 page 320 currentSlotId 0)</p>
<p>Slot 0 Column 1 Offset 0&#215;4 Length 4 Length (physical) 4</p>
<p>c1 = 1</p>
<p>Slot 0 Column 2 Offset 0&#215;8 Length 4 Length (physical) 4</p>
<p>c2 = 3</p>
<p>Slot 0 Column 3 Offset 0&#215;13 Length 4 Length (physical) 4</p>
<p>c3 = test</p>
<p>Slot 0 Offset 0&#215;0 Length 0 Length (physical) 0</p>
<p>KeyHashValue = (8194443284a0)</p></blockquote>
<p>Specifically at this point we see that the Version Pointer now has a value in it. This tells us that the SQL Server has put a copy of the original page into the tempdb database so that we can read it.</p>
<p>A question comes up as to what happens to the page when this row information is added.  Specifically does the page split because of this additional 14 bytes of new data per row.  The answer to this question is “it depends”.  In my testing that I did when I updated a single row the page didn’t split, mostly this would be because there was some free space in the database page.  When I updated rows 2-40 and looked at DBCC IND I saw that in fact the page had split.</p>
<p>Looking at the values within the page there are now 159 rows in the page which was the original database page when there were 322 rows within the database page.  The remainder of the rows were copied into a new database page.</p>
<p>Now that we’ve identified that SQL Server is going to be page splitting older database pages, potentially like crazy what can we do about it?  The answer to that question is to just deal with it and to decrease the fill factor as needed so that page splits happen as little as possible.</p>
<p>To make matters worse when we rebuild the index on the table and look at the output from DBCC PAGE again we can see that the additional flag has been removed from row 1 (seen below).  This tells us that no only will this problem come up the first time that data is modified, it’ll come up every time that index rebuilds are done when the data is changed for the first time after the rebuild.</p>
<blockquote><p>Slot 0 Offset 0&#215;60 Length 23</p>
<p>Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 23<br />
Memory Dump @0x000000003E0CA060</p>
<p>0000000000000000:   30000c00 01000000 03000000 03000001 00170074  0&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;t<br />
0000000000000014:   657374                                        est</p>
<p>Slot 0 Column 1 Offset 0&#215;4 Length 4 Length (physical) 4</p>
<p>c1 = 1</p>
<p>Slot 0 Column 2 Offset 0&#215;8 Length 4 Length (physical) 4</p>
<p>c2 = 3</p>
<p>Slot 0 Column 3 Offset 0&#215;13 Length 4 Length (physical) 4</p>
<p>c3 = test</p>
<p>Slot 0 Offset 0&#215;0 Length 0 Length (physical) 0</p>
<p>KeyHashValue = (8194443284a0)</p></blockquote>
<p><span style="color: #000000">Changing the data again, this time changing the first 40 rows (id values 1-40) the new flag comes into place as expected.  If we reorganize the index instead of doing a rebuild this time the flags are left in place.</span></p>
<p><span style="color: #000000">This tells us that the better option for doing index maintenance on databases which are being protected by AlwaysOn Availability Groups is going to be to use reorganize commands instead of rebuild commands.  This way the 14 byte pointer isn’t removed from the rows so that when they are modified the additional 14 bytes of data doesn’t need to be added.</span></p>
<p>If you’ve got rows which are changed all the time then this will be a way to handle it.  If the rows never change after the data is reorged then it may or may not be something worth worrying about.</p>
<p><span style="color: #000000">Hopefully this helps answer the questions of what these extra bytes are for and how we can deal with them. </span></p>
<p><span style="color: #000000">Denny </span></p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/extra-bytes-per-row-with-alwayson-availability-groups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NOLOCK is not a turbo button</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/nolock-is-not-a-turbo-button/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/nolock-is-not-a-turbo-button/#comments</comments>
		<pubDate>Wed, 23 Jan 2013 09:00:26 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[CREATE INDEX]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Execution Plans]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[SELECT statement]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[T/SQL]]></category>
		<category><![CDATA[Tables]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/?p=1574</guid>
		<description><![CDATA[All to often when talking to developers they put the WITH (NOLOCK) table hint in place to speed up queries without understanding what the table hint does.  I&#8217;ve even run across companies that have policies in place that every select statement must have the WITH (NOLOCK) table hint. The WITH (NOLOCK) table hint isn&#8217;t a [...]]]></description>
				<content:encoded><![CDATA[<p>All to often when talking to developers they put the WITH (NOLOCK) table hint in place to speed up queries without understanding what the table hint does.  I&#8217;ve even run across companies that have policies in place that every select statement must have the WITH (NOLOCK) table hint.</p>
<p>The WITH (NOLOCK) table hint isn&#8217;t a go faster button for SQL Server.  It has actual implications to the data which is being returned by the query.  The biggest of these implications is that the data might not be correct.  You see the WITH (NOLOCK) table hint uses dirty reads to return the data, so it basically ignores the locks which other queries have taken.  This is why the query appears to run faster, because the query isn&#8217;t being blocked any more.  The proper approach would be to find the query which is causing the extended blocking and figure out why it is taking so long to run, and fix the performance problems of that query.</p>
<p>The only go faster button that is available in SQL Server is the CREATE INDEX statement.  Anything else isn&#8217;t truly a go faster button, and has other side effects which must be understood before being implemented.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/nolock-is-not-a-turbo-button/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>We get many warnings in our SQL error log about I/O requests taking longer than 15 seconds to complete. What do we do in such scenario?</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/we-get-many-warnings-in-our-sql-error-log-about-io-requests-taking-longer-than-15-seconds-to-complete-what-do-we-do-in-such-scenario/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/we-get-many-warnings-in-our-sql-error-log-about-io-requests-taking-longer-than-15-seconds-to-complete-what-do-we-do-in-such-scenario/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 14:00:00 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Index]]></category>
		<category><![CDATA[Index Scan]]></category>
		<category><![CDATA[Index Seek]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Storage]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/we-get-many-warnings-in-our-sql-error-log-about-io-requests-taking-longer-than-15-seconds-to-complete-what-do-we-do-in-such-scenario/</guid>
		<description><![CDATA[There are a few things which you will want to look at.  First make sure that you have enough RAM for the database to use.  Without enough RAM in the SQL Server you’ll begin putting extra load on the disks because the same data is being pulled into the buffer cache from the disk over [...]]]></description>
				<content:encoded><![CDATA[<p>There are a few things which you will want to look at.  First make sure that you have enough RAM for the database to use.  Without enough RAM in the SQL Server you’ll begin putting extra load on the disks because the same data is being pulled into the buffer cache from the disk over and over.</p>
<p>The second thing to check is that you don’t need to add any additional indexes.  If your queries are doing scan’s which they shouldn’t be then this will put extra load on the disks.</p>
<p>If everything else looks good it’s time to get the boss to open their checkbook and buy more disks, or faster disks.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/we-get-many-warnings-in-our-sql-error-log-about-io-requests-taking-longer-than-15-seconds-to-complete-what-do-we-do-in-such-scenario/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slide Decks for the OC SQL Users Group</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/slide-decks-for-the-oc-sql-users-group/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/slide-decks-for-the-oc-sql-users-group/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 03:40:43 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[DACPAC]]></category>
		<category><![CDATA[Execution Plans]]></category>
		<category><![CDATA[In Person Events]]></category>
		<category><![CDATA[OC SQL User Group]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/?p=1233</guid>
		<description><![CDATA[Tomorrow I&#8217;ll be speaking at the Orange County SQL Server Users Group.  I&#8217;ll be presenting two sessions at the meeting.  One will be &#8220;Exploring the DAC and everyone&#8217;s favorite feature the DACPAC&#8220;, and the other will be &#8220;Reading the SQL Server Execution Plan&#8220;. The meeting starts at 6:30pm, and I believe that there will be [...]]]></description>
				<content:encoded><![CDATA[<p>Tomorrow I&#8217;ll be speaking at the <a href="http://www.sqloc.com/">Orange County SQL Server Users Group</a>.  I&#8217;ll be presenting two sessions at the meeting.  One will be &#8220;<a href="http://www.mrdenny.com/downloads/2010.08.05_OCSQLUG/Exploring the DAC and everyone's favorite feature the DACPAC.pptx">Exploring the DAC and everyone&#8217;s favorite feature the DACPAC</a>&#8220;, and the other will be &#8220;<a href="http://www.mrdenny.com/downloads/2010.08.05_OCSQLUG/Reading the SQL Server Execution Plan.pptx">Reading the SQL Server Execution Plan</a>&#8220;.</p>
<p>The meeting starts at 6:30pm, and I believe that there will be pizza provided and who doesn&#8217;t like pizza and a DACPAC discussion.</p>
<p>The user group meets at the New Horizons Computer Learning Center in Anaheim.</p>
<p>1900 S. State College Blvd.<br />
Suite 100<br />
Anaheim, CA 92806</p>
<p>It&#8217;s right behind Angel&#8217;s stadium (or what ever its called this month), you can&#8217;t miss it.</p>
<p>I&#8217;ll have some SWAG with me, but not a whole lot (my supplies are starting to run low).</p>
<p>See you there.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/slide-decks-for-the-oc-sql-users-group/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dates can easily be the hardest datatype to work with.</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/dates-can-easily-be-the-hardest-datatype-to-work-with/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/dates-can-easily-be-the-hardest-datatype-to-work-with/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 11:00:03 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Index Performance]]></category>
		<category><![CDATA[Index Scan]]></category>
		<category><![CDATA[Index Seek]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[T/SQL]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/?p=693</guid>
		<description><![CDATA[The datetime data type can be one of the hardest to work with when it comes to index optimization.  Most queries that use a datetime data type for filtering (part of the where clause) only want to match the date portion of the value.  Most people handle this via a convert function around the date [...]]]></description>
				<content:encoded><![CDATA[<p>The datetime data type can be one of the hardest to work with when it comes to index optimization.  Most queries that use a datetime data type for filtering (part of the where clause) only want to match the date portion of the value.  Most people handle this via a convert function around the date column.  This causes the index that you create to become useless as the convert function causes the <a href="http://itknowledgeexchange.techtarget.com/sql-server/back-to-basics-whats-the-difference-between-a-scan-and-a-seek/" target="_blank">index to be scanned not seeked</a>.</p>
<p><span id="more-693"></span></p>
<p>You can see this yourself by creating a table, with a date field, then stuff some records into that table.</p>
<pre class="brush: sql; title: ; notranslate">CREATE TABLE sample_table
(id INT IDENTITY(1,1) PRIMARY KEY,
dt DATETIME)
go
CREATE INDEX ix_sample_table ON dbo.sample_table
(dt)
go
INSERT INTO sample_table
(dt)
SELECT '1/1/2000 15:00:00'
UNION
SELECT '1/2/2000 12:00:00'
UNION
SELECT '1/3/2000 08:00:00'
go</pre>
<p>You can now query the dt column and use the convert function.  When you view the execution plan you&#8217;ll see that an index scan is being used.</p>
<pre class="brush: sql; title: ; notranslate">SELECT id, dt
FROM sample_table
WHERE CONVERT(varchar(10), dt, 101) = '01/01/2000'</pre>
<p><a href="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/index_scan.jpg"><img class="alignnone size-medium wp-image-688" src="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/index_scan.jpg" alt="" width="446" height="149" /></a></p>
<p>But it you use the BETWEEN operator instead of the = operator you&#8217;ll see the engine using an index seek instead of the index scan.</p>
<pre class="brush: sql; title: ; notranslate">SELECT id, dt
FROM sample_table
WHERE dt BETWEEN '01/01/2000' AND '01/02/2000'</pre>
<p><a href="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/index_seek.jpg"><img class="alignnone size-medium wp-image-689" src="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/index_seek.jpg" alt="" width="540" height="130" /></a></p>
<p>Now the same thing applies when using other functions to the datetime column in the table.  For example if you were to have a system where people need to search based on the timezone where the data is stored in UTC time, but searching needs to happen based on the users time zone.</p>
<p>The easiest way to do this would be to put a dateadd function around the dt field.  However even when using the BETWEEN operator you still use an index scan, instead of the seek.  In this case I&#8217;m searching against the pacific timezone.</p>
<pre class="brush: sql; title: ; notranslate">SELECT id, dt
FROM sample_table
WHERE dateadd(mi, -420, dt) BETWEEN '01/01/2000' AND '01/02/2000'</pre>
<p><a href="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/scan_with_static_offset.jpg"><img class="alignnone size-medium wp-image-690" src="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/scan_with_static_offset.jpg" alt="" width="826" height="130" /></a></p>
<p>Now, if you switch the -420 to 420, and put the DATEADD function around the dates in the BETWEEN operator the index seek will be preserved.  The query looks a little strange, but that&#8217;s ok.  It&#8217;s the end result that we are looking for here.</p>
<pre class="brush: sql; title: ; notranslate">SELECT id, dt
FROM sample_table
WHERE dt BETWEEN dateadd(mi, 420, '01/01/2000') AND dateadd(mi, 420, '01/02/2000')</pre>
<p><a href="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/seek_with_static_offset.jpg"><img class="alignnone size-medium wp-image-691" src="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/seek_with_static_offset.jpg" alt="" width="664" height="138" /></a></p>
<p>Now if you have the UtcOffset that you want to use stored in another table such as an Account table.  We&#8217;ll recreate the sample_table to go with this.</p>
<pre class="brush: sql; title: ; notranslate">CREATE TABLE sample_table
(id INT IDENTITY(1,1) PRIMARY KEY,
dt DATETIME,
AccountId int)

CREATE TABLE Account
(AccountId INT PRIMARY KEY,
UtcOffset INT)
go
CREATE INDEX ix_sample_table ON dbo.sample_table
(dt)
INCLUDE (AccountId)
go
INSERT INTO sample_table
(dt, AccountId)
SELECT '1/1/2000 15:00:00', 1
UNION
SELECT '1/2/2000 12:00:00', 2
UNION
SELECT '1/3/2000 08:00:00', 1

INSERT INTO Account
SELECT 1, -420
UNION
SELECT 2, -300</pre>
<p>In order to make this work, you have to take the UtcOffset value *-1 so that the date is adjusted in the correct direction to make the query work.</p>
<pre class="brush: sql; title: ; notranslate">SELECT id, dt
FROM sample_table
JOIN Account on sample_table.AccountId = Account.AccountId
WHERE dt BETWEEN dateadd(mi, Account.UtcOffset*-1, '01/01/2000') AND dateadd(mi, Account.UtcOffset*-1, '01/02/2000')
</pre>
<p><a href="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/seek_with_dynamic_offset.jpg"><img class="alignnone size-medium wp-image-692" src="http://cdn.ttgtmedia.com/ITKE/uploads/blogs.dir/20/files/2009/08/seek_with_dynamic_offset.jpg" alt="" width="721" height="217" /></a></p>
<p>(Ignore the Clustered Index Scan on the Account table, correcting that isn&#8217;t the goal of this post.</p>
<p>Hopefully you find this technique useful.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/dates-can-easily-be-the-hardest-datatype-to-work-with/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>SoCal Code Camp &#8211; LA #2 has been announced</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/socal-code-camp-la-sharp-2-has-been-announced/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/socal-code-camp-la-sharp-2-has-been-announced/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 21:11:38 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Execution Plans]]></category>
		<category><![CDATA[In Person Events]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[SoCal Code Camp]]></category>
		<category><![CDATA[Storage]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/socal-code-camp-la-sharp-2-has-been-announced/</guid>
		<description><![CDATA[The SoCal Code Camp website has been reset and is ready for the next Code Camp.  This code camp will be the second camp camp that we are doing up in LA.  This time it is November 21st and 22nd and is being hosted at USC&#8217;s campus again.  (There&#8217;s a second site setup for the [...]]]></description>
				<content:encoded><![CDATA[<p>The <a title="SoCal Code Camp" href="http://www.socalcodecamp.com/" target="_blank">SoCal Code Camp</a> website has been reset and is ready for the next Code Camp.  This code camp will be the second camp camp that we are doing up in LA.  This time it is November 21st and 22nd and is being hosted at USC&#8217;s campus again.  (There&#8217;s a second site setup for the <a href="http://www.lacodecamp.com/" target="_blank">LA Code Camp</a> specifically so be sure to check that site out as well.)<span id="more-672"></span></p>
<p>This time the LA Code Camp will be the weekend after PDC this time as the weekend before is a home football game.  Apparently the home games are pretty popular so they need all the available parking for the game, especially since we were right next to the stadium last time.</p>
<p>There will be all sorts of great presenters giving presentations at this event.  Hopefully a bunch of the PDC speakers will be coming and giving presentations.</p>
<p>I&#8217;ve got three presentations lined up so far (more may come, I&#8217;ve got time to decide).</p>
<ul>
<li><a href="http://www.socalcodecamp.com/session.aspx?sid=7798c7f2-0177-4d91-b9ad-8e1880ebe4a4">Reading the SQL Server Execution Plan</a></li>
<li><a href="http://www.socalcodecamp.com/session.aspx?sid=18c637ce-60e5-4edc-8f97-72d95351e69c">SQL Server Indexing for the Client Developer</a></li>
<li><a href="http://www.socalcodecamp.com/session.aspx?sid=16653a24-69bf-4845-8de5-cc007c043ca5">Storage for the DBA</a></li>
</ul>
<p>In the Reading the SQL Server Execution Plan session I&#8217;ll be going over how to read the execution plan, as well as how to get the SQL Server to change it&#8217;s mind.</p>
<p>In the SQL Server Indexing for the Client Developer I&#8217;ll be showing proper techniques for SQL Server indexing.</p>
<p>In the Storage for the DBA session I&#8217;ll be going over some best practices for how to setup your storage, as well as how to talk to your storage admin so that you can get the best storage possible for the server, while still keeping the finances of buying storage in mind.  During the session (network access permitting) we&#8217;ll be looking at a production EMC storage array to see what the Storage Admin sees and how what he sees translates to what we DBAs see on the server.</p>
<p>Full session descriptions are available on to SoCal Code Camp site or via the links above.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/socal-code-camp-la-sharp-2-has-been-announced/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Viewing SQL Server Plan Guides</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/viewing-sql-server-plan-guides/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/viewing-sql-server-plan-guides/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 15:00:06 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Code Snippet]]></category>
		<category><![CDATA[Plan Guides]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[sys.plan_guides]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/?p=280</guid>
		<description><![CDATA[So you&#8217;ve saved a plan guide into your SQL server, and you want to look at the plan.  You can Query the sys.plan_guides catalog view and see the data exactly as you entered it, which works fine if you just have a hint in there.  But if you have a full XML query plan that [...]]]></description>
				<content:encoded><![CDATA[<p>So you&#8217;ve saved a plan guide into your SQL server, and you want to look at the plan.  You can Query the sys.plan_guides catalog view and see the data exactly as you entered it, which works fine if you just have a hint in there.  But if you have a full XML query plan that isn&#8217;t going to do you a lot of good since SSMS isn&#8217;t going to want to show you the all the XML as it is probably longer than it wants to display.</p>
<p>This little query should help you with that.  You may need adjust it slightly to account for extra spaces in your plan guide, I tried to account for double spaces, but if you have more than two spaces anywhere in the top part you&#8217;ll need to tweak it.</p>
<p><span id="more-280"></span><code>select cast(replace(replace(replace(hints, '  ', ' '), 'OPTION (USE PLAN N''', ''), ''')', '') as xml), *<br />
from sys.plan_guides</code></p>
<p>This will give you XM that you can click on, which should open right up in SSMS as a query plan (if using SQL Server 2008, if you are using the SQL 2005 SSMS you&#8217;ll need to save the XML file and rename it to *.sqlplan and open it in SSMS).</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/viewing-sql-server-plan-guides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Back To Basics: What&#8217;s the difference between a Scan and a Seek?</title>
		<link>http://itknowledgeexchange.techtarget.com/sql-server/back-to-basics-whats-the-difference-between-a-scan-and-a-seek/</link>
		<comments>http://itknowledgeexchange.techtarget.com/sql-server/back-to-basics-whats-the-difference-between-a-scan-and-a-seek/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 13:00:23 +0000</pubDate>
		<dc:creator>Denny Cherry</dc:creator>
				<category><![CDATA[Back To Basics]]></category>
		<category><![CDATA[Index Performance]]></category>
		<category><![CDATA[Index Scan]]></category>
		<category><![CDATA[Index Seek]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Table Scan]]></category>

		<guid isPermaLink="false">http://itknowledgeexchange.techtarget.com/sql-server/back-to-basics-whats-the-difference-between-a-scan-and-a-seek/</guid>
		<description><![CDATA[There are a few basic operations which SQL will perform when looking for the data that you need.  Here they are listed in the order of worst to best. Table Scan Clustered Index Scan Index Scan Clustered Index Seek Index Seek The basic rule to follow is Scans are bad, Seeks are good. When SQL [...]]]></description>
				<content:encoded><![CDATA[<p>There are a few basic operations which SQL will perform when looking for the data that you need.  Here they are listed in the order of worst to best.</p>
<ul>
<li>Table Scan</li>
<li>Clustered Index Scan</li>
<li>Index Scan</li>
<li>Clustered Index Seek</li>
<li>Index Seek</li>
</ul>
<p>The basic rule to follow is Scans are bad, Seeks are good.</p>
<p><span id="more-213"></span>When SQL Server does a scan it loads the object which it wants to read from disk into memory, then reads through that object from top to bottom looking for the records that it needs.</p>
<p>When SQL Server does a seek it knows where in the index that the data is going to be, so it loads up the index from disk, goes directly to the part of the index that it needs and reads to where the data that it needs ends.  This is obviously a must more efficient operation than a scan, as SQL already knows where the data is that it is looking for.</p>
<p>When SQL Server is looking for your data probably one of the largest things which will make SQL Server switch from a seek to a scan is when some of the columns are you looking for are not included in the index you want it to use.  Most often this will have SQL Server fall back to doing a clustered index scan, since the Clustered index contains all the columns in the table.  This is one of the biggest reasons (in my opinion at least) that we now have the ability to INCUDE columns in an index, without adding those columns to the indexed columns of the index.   By including the additional columns in the index we increase the size of the index, but we allow SQL Server to read the index, without having to go back to the clustered index, or to the table it self to get these values.</p>
<p>We&#8217;ll look at this more shortly when we look at execution plans.</p>
<p>Denny</p>
<!-- wpms-network-global-inserts -->]]></content:encoded>
			<wfw:commentRss>http://itknowledgeexchange.techtarget.com/sql-server/back-to-basics-whats-the-difference-between-a-scan-and-a-seek/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
