<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'Performance', 'page splits', and 'uniqueidentifier'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=Performance,page+splits,uniqueidentifier&amp;orTags=0</link><description>Search results matching tags 'Performance', 'page splits', and 'uniqueidentifier'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Some Simple Code To Show The Difference Between Newid And Newsequentialid</title><link>http://sqlblog.com/blogs/denis_gobo/archive/2009/02/05/11743.aspx</link><pubDate>Thu, 05 Feb 2009 17:52:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:11743</guid><dc:creator>Denis Gobo</dc:creator><description>&lt;p&gt;Some Simple Code To Show The Difference Between Newid And Newsequentialid&lt;br&gt;&lt;br&gt;In SQL Server 2000 we got the uniqueidentifier data type and the newid() function&lt;br&gt;&lt;br&gt;Lots of people thought that newid() would be very handy to create some unique values across all databases.&lt;br&gt;Newid() is nice but it has a little side effect; it causes terrible page splits because it is a random value. SQL Server 2005 introduced newsequentialid() where each value generated by the function is always greater than the previous value.&lt;br&gt;&lt;br&gt;Let's take a look&lt;br&gt;&lt;br&gt;&lt;br&gt;First we will create these two tables&lt;/p&gt;&lt;br&gt;&lt;div style="display:block;" class="tsql" id="cb78575"&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;CREATE&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; TestGuid1 &lt;span&gt;(&lt;/span&gt;Id &lt;span&gt;UNIQUEIDENTIFIER&lt;/span&gt; not null &lt;span&gt;DEFAULT&lt;/span&gt; newid&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;SomeDate &lt;span&gt;DATETIME&lt;/span&gt;, batchNumber &lt;span&gt;BIGINT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;CREATE&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; TestGuid2 &lt;span&gt;(&lt;/span&gt;Id &lt;span&gt;UNIQUEIDENTIFIER&lt;/span&gt; not null &lt;span&gt;DEFAULT&lt;/span&gt; newsequentialid&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;SomeDate &lt;span&gt;DATETIME&lt;/span&gt;, batchNumber &lt;span&gt;BIGINT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;now run this block of code to insert 1000 rows in each table&lt;br&gt;&lt;br&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;SET&lt;/span&gt; &lt;span&gt;NOCOUNT&lt;/span&gt; &lt;span&gt;ON&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;INSERT&lt;/span&gt; TestGuid1 &lt;span&gt;(&lt;/span&gt;SomeDate,batchNumber&lt;span&gt;)&lt;/span&gt; &lt;span&gt;VALUES&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;GETDATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;go &lt;span&gt;1000&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;SET&lt;/span&gt; &lt;span&gt;NOCOUNT&lt;/span&gt; &lt;span&gt;ON&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;INSERT&lt;/span&gt; TestGuid2 &lt;span&gt;(&lt;/span&gt;SomeDate,batchNumber&lt;span&gt;)&lt;/span&gt; &lt;span&gt;VALUES&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;GETDATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;go &lt;span&gt;1000&lt;/span&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;Create these two clustered indexes&lt;br&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;CREATE&lt;/span&gt; &lt;span&gt;CLUSTERED&lt;/span&gt; &lt;span&gt;INDEX&lt;/span&gt; ix_id1 &lt;span&gt;ON&lt;/span&gt; TestGuid1&lt;span&gt;(&lt;/span&gt;id&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;CREATE&lt;/span&gt; &lt;span&gt;CLUSTERED&lt;/span&gt; &lt;span&gt;INDEX&lt;/span&gt; ix_id2 &lt;span&gt;ON&lt;/span&gt; TestGuid2&lt;span&gt;(&lt;/span&gt;id&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;Run the code below&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;DBCC&lt;/span&gt; showcontig &lt;span&gt;(&lt;/span&gt;&lt;span&gt;'TestGuid1'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;WITH&lt;/span&gt; tableresults&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;DBCC&lt;/span&gt; showcontig &lt;span&gt;(&lt;/span&gt;&lt;span&gt;'TestGuid2'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &amp;nbsp;&lt;span&gt;WITH&lt;/span&gt; tableresults&lt;/div&gt;&lt;br&gt;&lt;br&gt;You will see that AvgerageFreeBytes is the same for both tables&lt;br&gt;&lt;br&gt;What about the inserts themselves? Run this code below&lt;br&gt;&lt;br&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SELECT&lt;/span&gt; batchNumber,&lt;span&gt;DATEDIFF&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;ms,&lt;span&gt;MIN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;FROM&lt;/span&gt; TestGuid1&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;GROUP&lt;/span&gt; &lt;span&gt;BY&lt;/span&gt; batchNumber&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SELECT&lt;/span&gt; batchNumber,&lt;span&gt;DATEDIFF&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;ms,&lt;span&gt;MIN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;FROM&lt;/span&gt; TestGuid2&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;GROUP&lt;/span&gt; &lt;span&gt;BY&lt;/span&gt; batchNumber&lt;/div&gt;&lt;br&gt;&lt;br&gt;The table with the Newsequentialid did the inserts about 40% faster.&lt;br&gt;&lt;br&gt;Now we will insert 1000 rows in each table again&lt;br&gt;&lt;br&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SET&lt;/span&gt; &lt;span&gt;NOCOUNT&lt;/span&gt; &lt;span&gt;ON&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;INSERT&lt;/span&gt; TestGuid1 &lt;span&gt;(&lt;/span&gt;SomeDate,batchNumber&lt;span&gt;)&lt;/span&gt; &lt;span&gt;VALUES&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;GETDATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;go &lt;span&gt;1000&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SET&lt;/span&gt; &lt;span&gt;NOCOUNT&lt;/span&gt; &lt;span&gt;ON&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;INSERT&lt;/span&gt; TestGuid2 &lt;span&gt;(&lt;/span&gt;SomeDate,batchNumber&lt;span&gt;)&lt;/span&gt; &lt;span&gt;VALUES&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;GETDATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;go &lt;span&gt;1000&lt;/span&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;No we will look again what happened&lt;br&gt;&lt;br&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;DBCC&lt;/span&gt; showcontig &lt;span&gt;(&lt;/span&gt;&lt;span&gt;'TestGuid1'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;WITH&lt;/span&gt; tableresults&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;DBCC&lt;/span&gt; showcontig &lt;span&gt;(&lt;/span&gt;&lt;span&gt;'TestGuid2'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &amp;nbsp;&lt;span&gt;WITH&lt;/span&gt; tableresults&lt;/div&gt;&lt;br&gt;&lt;br&gt;Wow the first table uses 21 pages while the second one uses 12.&lt;br&gt;AvgerageFreeBytes is 3524 bytes per page in the first table and only 96 bytes per page in the second table. Obviously newsequentialid is the better choice.&lt;br&gt;&lt;br&gt;Running the code below you will see that newid is still slower than newsequentialid by about 16% or so for batch 2&lt;br&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SELECT&lt;/span&gt; batchNumber,&lt;span&gt;DATEDIFF&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;ms,&lt;span&gt;MIN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;FROM&lt;/span&gt; TestGuid1&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;GROUP&lt;/span&gt; &lt;span&gt;BY&lt;/span&gt; batchNumber&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SELECT&lt;/span&gt; batchNumber,&lt;span&gt;DATEDIFF&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;ms,&lt;span&gt;MIN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;FROM&lt;/span&gt; TestGuid2&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;GROUP&lt;/span&gt; &lt;span&gt;BY&lt;/span&gt; batchNumber&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;Now we will insert 10000 rows and then look at freespace and duration again&lt;br&gt;&lt;br&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SET&lt;/span&gt; &lt;span&gt;NOCOUNT&lt;/span&gt; &lt;span&gt;ON&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;INSERT&lt;/span&gt; TestGuid1 &lt;span&gt;(&lt;/span&gt;SomeDate,batchNumber&lt;span&gt;)&lt;/span&gt; &lt;span&gt;VALUES&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;GETDATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;go &lt;span&gt;10000&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SET&lt;/span&gt; &lt;span&gt;NOCOUNT&lt;/span&gt; &lt;span&gt;ON&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;INSERT&lt;/span&gt; TestGuid2 &lt;span&gt;(&lt;/span&gt;SomeDate,batchNumber&lt;span&gt;)&lt;/span&gt; &lt;span&gt;VALUES&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;GETDATE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;go &lt;span&gt;10000&lt;/span&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;DBCC&lt;/span&gt; showcontig &lt;span&gt;(&lt;/span&gt;&lt;span&gt;'TestGuid1'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;WITH&lt;/span&gt; tableresults&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;DBCC&lt;/span&gt; showcontig &lt;span&gt;(&lt;/span&gt;&lt;span&gt;'TestGuid2'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &amp;nbsp;&lt;span&gt;WITH&lt;/span&gt; tableresults&lt;/div&gt;&lt;br&gt;&lt;br&gt;The first table uses 117 pages while the second one uses 80.&lt;br&gt;AvgerageFreeBytes is 2574 bytes per page in the first table and only 21 bytes per page in the second table. &lt;br&gt;&lt;br&gt;Running the code below you will see that newid is still slower than newsequentialid by about 40% or so for batch 3&lt;br&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SELECT&lt;/span&gt; batchNumber,&lt;span&gt;DATEDIFF&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;ms,&lt;span&gt;MIN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;FROM&lt;/span&gt; TestGuid1&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;GROUP&lt;/span&gt; &lt;span&gt;BY&lt;/span&gt; batchNumber&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;SELECT&lt;/span&gt; batchNumber,&lt;span&gt;DATEDIFF&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;ms,&lt;span&gt;MIN&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;,&lt;span&gt;MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;SomeDate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-left:medium none;" class="li2"&gt;&lt;span&gt;FROM&lt;/span&gt; TestGuid2&lt;/div&gt;&lt;div style="border-left:medium none;" class="li1"&gt;&lt;span&gt;GROUP&lt;/span&gt; &lt;span&gt;BY&lt;/span&gt; batchNumber&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;Clean up&lt;br&gt;&lt;span&gt;DROP&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; TestGuid2,TestGuid1&lt;br&gt;&lt;br&gt;So that is all, do you use newid or newsequentialid and if you do use newid did you experience fragmentation or performance problems because of it?
</description></item></channel></rss>