<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Life as a SQL Swiss Army Knife</title>
        <link>http://weblogs.sqlteam.com/mikef/Default.aspx</link>
        <description>..or maybe I'm just the guy with the shovel behind the horses in the parade</description>
        <language>en-US</language>
        <copyright>Mike Femenella</copyright>
        <generator>Subtext Version 2.5.1.0</generator>
        <image>
            <title>Life as a SQL Swiss Army Knife</title>
            <url>http://weblogs.sqlteam.com/images/RSS2Image.gif</url>
            <link>http://weblogs.sqlteam.com/mikef/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>The 5 stages reviewing bad TSQL</title>
            <link>http://weblogs.sqlteam.com/mikef/archive/2012/04/16/the-5-stages-reviewing-bad-tsql-again.aspx</link>
            <description>&lt;strong&gt;&lt;p&gt;&lt;strong&gt;&lt;h4&gt;I'm working with an app team that is light on TSQL expertise this week and couldn't help but draw a parallel to the 5 stages of grieving. &lt;/h4&gt; &lt;/strong&gt;&lt;/p&gt;&lt;/strong&gt; &lt;ol&gt;   &lt;li&gt;Denial: There’s nothing wrong with the code SQL Server has a bug in it. There is a network problem.&lt;/li&gt;    &lt;li&gt;Anger: You’re doing what in your code?! Why on earth are you doing that? That’s crazy.&lt;/li&gt;    &lt;li&gt;Bargaining: Fine you can keep your cursor but let’s speed things up a bit.&lt;/li&gt;    &lt;li&gt;Depression: Ugh, this is so horrible I’m never going to be able to fix all of it.&lt;/li&gt;    &lt;li&gt;Acceptance: Ok, we’re screwed and we know we’re screwed. This is going to hurt…&lt;/li&gt; &lt;/ol&gt;&lt;img src="http://weblogs.sqlteam.com/mikef/aggbug/61409.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mike Femenella</dc:creator>
            <guid>http://weblogs.sqlteam.com/mikef/archive/2012/04/16/the-5-stages-reviewing-bad-tsql-again.aspx</guid>
            <pubDate>Mon, 16 Apr 2012 19:56:10 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/mikef/archive/2012/04/16/the-5-stages-reviewing-bad-tsql-again.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/mikef/comments/commentRss/61409.aspx</wfw:commentRss>
        </item>
        <item>
            <title>How to tell what your insert, update is doing</title>
            <link>http://weblogs.sqlteam.com/mikef/archive/2010/09/02/how-to-tell-what-your-insert-update-or-delete-is.aspx</link>
            <description>&lt;p&gt;Lately I’ve been working on a data migration SSIS package for a customer and some of it is just a straight forward execute sql tasks in SSIS on some very large tables. I pull 10 million rows into a staging area, massage some data into the proper format, insert it into it’s final production table resting place, easy enough. I’m testing it on a very low powered 32 bit server and it takes a while. At one point today I started wondering if it was just locked up or was still running. &lt;/p&gt;  &lt;p&gt;I’ve used the sys.partitions table before as an alternate method of getting row counts for a table as it already has that information handy for me. This time I was querying the table while the insert was running and I was able to see exactly what was happening. The code below will walk you through an easy example. This will work the same in 2005, or 2008.&lt;/p&gt;  &lt;p&gt;First, just create a throw away table:&lt;/p&gt;  &lt;p&gt;Create table Loadtest    &lt;br /&gt;(     &lt;br /&gt;IDVal int identity(1,1),     &lt;br /&gt;CustomerName varchar(200),     &lt;br /&gt;CustomerCity varchar(200)     &lt;br /&gt;)&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Now let’s create a looping insert that gives us enough time to look at things. You can just stop it when you have had enough. It’s nothing exciting here, I’m just creating an loop 2 million times and doing an insert..like I said, stop it when you’ve had enough:&lt;/p&gt;  &lt;p&gt;declare @counter int    &lt;br /&gt;set @counter=2000000     &lt;br /&gt;While @counter&amp;gt;0     &lt;br /&gt;BEGIN     &lt;br /&gt;    Insert into LoadTest(CustomerName,CustomerCity)     &lt;br /&gt;        values('Mike Femenella','Matthews')     &lt;br /&gt;        SET @counter=@counter-1     &lt;br /&gt;END        &lt;/p&gt;  &lt;p&gt;While your loop is running, open up another query analyzer window to the same database and run this:&lt;/p&gt;  &lt;p&gt;SELECT sp.index_id,Rows,si.name,si.type_desc    &lt;br /&gt;      FROM sys.partitions sp     &lt;br /&gt;      inner join sys.indexes si     &lt;br /&gt;      on sp.object_id=si.object_id     &lt;br /&gt;      AND sp.index_id=si.index_id     &lt;br /&gt;      where object_name(sp.object_id)='LoadTest'&lt;/p&gt;  &lt;p&gt;Since the table is not indexed you’ll see the row count and that it’s populating the heap, hit F5 a few times and you can watch the rows field increment. If you have doubts your insert statement is actually running, this is a good way to check that it is alive and you can also get an idea of it’s progress if you have a guess as to how many rows “should” be there.&lt;/p&gt;  &lt;p&gt;--Unindexed, you see the heap being populated.      &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;   index_id        Rows    name    type_desc    &lt;br /&gt;    0                   24252    NULL    HEAP&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;So that was mildly interesting and sort of cool. Of course we can take it a step further (and I always love doing that). Go ahead and stop the loop when you have have a million or so rows in there, you need a large amount of data in the LoadTest table so you have enough time to run the sys.partitions query again. I was letting my loop run while writing the first part of the blog so I have 2 million rows in LoadTest.&lt;/p&gt;  &lt;p&gt;Let’s create a mirror image of our LoadTest table and since I’m at the end of my work week and feeling very creative I’m going to call it LoadTest_Copy, go ahead and F5 and create the table.. Award winning material here isn’t it?&lt;/p&gt;  &lt;p&gt;Create table Loadtest_Copy    &lt;br /&gt;(     &lt;br /&gt;IDVal int ,     &lt;br /&gt;CustomerName varchar(200),     &lt;br /&gt;CustomerCity varchar(200)     &lt;br /&gt;) &lt;/p&gt;  &lt;p&gt;GO    &lt;br /&gt;Create Clustered index ixc_IDVal on LoadTest_Copy(IDVal)     &lt;br /&gt;Create index ix_CustomerName on LoadTest_Copy(CustomerName)     &lt;br /&gt;Create index ix_CustomerCity on LoadTest_Copy(CustomerCity)&lt;/p&gt;  &lt;p&gt;GO&lt;/p&gt;  &lt;p&gt;In another window modify your sys.partition query and change the name from LoadTest to LoadTest_Copy. Run this now and you have 3 rows, one for the clustered index and one for each of the other indexes. Somewhat more realistic and more interesting.&lt;/p&gt;  &lt;p&gt;SELECT sp.index_id,Rows,si.name,si.type_desc    &lt;br /&gt;      FROM sys.partitions sp     &lt;br /&gt;      inner join sys.indexes si     &lt;br /&gt;      on sp.object_id=si.object_id     &lt;br /&gt;      AND sp.index_id=si.index_id     &lt;br /&gt;      where object_name(sp.object_id)='LoadTest_Copy'&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Results:&lt;/p&gt;  &lt;p&gt;index_id    Rows    name                           type_desc    &lt;br /&gt;1                0          ixc_IDVal                     CLUSTERED     &lt;br /&gt;2                0          ix_CustomerName       NONCLUSTERED     &lt;br /&gt;3                0          ix_CustomerCity         NONCLUSTERED&lt;/p&gt;  &lt;p&gt;Now, do an insert from LoadTest into LoadTest_Copy. Start it and then flip over to your sys.partition query, run it while the insert is happening and look at the results.&lt;/p&gt;  &lt;p&gt;You can keep hitting F5 and watch the numbers change. Notice it builds the clustered index first, which of course makes sense, and then will go through each of the other 2 indexes building them out.&lt;/p&gt;  &lt;p&gt;index_id    Rows         name                           type_desc    &lt;br /&gt;1                   449900    ixc_IDVal                    CLUSTERED     &lt;br /&gt;2                   0             ix_CustomerName      NONCLUSTERED     &lt;br /&gt;3                   0            ix_CustomerCity          NONCLUSTERED&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;index_id    Rows            name                      type_desc    &lt;br /&gt;1               2000000        ixc_IDVal                 CLUSTERED     &lt;br /&gt;2               1065245        ix_CustomerName   NONCLUSTERED     &lt;br /&gt;3               0                   ix_CustomerCity     NONCLUSTERED&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;index_id    Rows          name                      type_desc    &lt;br /&gt;1               2000000       ixc_IDVal                 CLUSTERED     &lt;br /&gt;2               2000000       ix_CustomerName   NONCLUSTERED     &lt;br /&gt;3               126137         ix_CustomerCity     NONCLUSTERED&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;And finally now that it’s done:&lt;/p&gt;  &lt;p&gt;index_id         Rows        name                       type_desc    &lt;br /&gt;1                    2000000    ixc_IDVal                  CLUSTERED     &lt;br /&gt;2                    2000000    ix_CustomerName    NONCLUSTERED     &lt;br /&gt;3                    2000000    ix_CustomerCity       NONCLUSTERED&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;So next time you’re wondering if your insert or update statement is actually doing anything useful, you can leverage some of the underlying DMV data to make sure things are still on track and it’s a good way to tell if you have time to run out for coffee. That’s the last SQL related thing I’m doing, time for vacation…cheers!&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/mikef/aggbug/61194.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mike Femenella</dc:creator>
            <guid>http://weblogs.sqlteam.com/mikef/archive/2010/09/02/how-to-tell-what-your-insert-update-or-delete-is.aspx</guid>
            <pubDate>Fri, 03 Sep 2010 00:15:44 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/mikef/archive/2010/09/02/how-to-tell-what-your-insert-update-or-delete-is.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/mikef/comments/commentRss/61194.aspx</wfw:commentRss>
        </item>
        <item>
            <title>SQL Saturday Atlanta: Intro To Performance Tuning</title>
            <link>http://weblogs.sqlteam.com/mikef/archive/2010/04/12/SQL-Saturday-Atlanta-Intro-To-Performance-Tuning.aspx</link>
            <description>&lt;p&gt;I'm looking forward to speaking in Atlanta on the 24th, will be fun to get back down that way to visit with some friends and present two topics that I really enjoy. &lt;/p&gt;  &lt;p&gt;First, an introduction to performance tuning. Performance tuning is a very wide and deep topic and we're staying close to the surface. I direct this class for newbie sql users who have less than 2 years of experience. It's all the things I wish someone would have told me in my first 2 years about what to look for when the database was slow...or allegedly slow I should say. We'll cover using profiler to find slow performing queries and how to save the data off to a table as well as a tour of other features. The difference between clustered, non clustered and covering indexes. How to look at and understand an execution plan (at a high level) and finally the difference between a temp table and a table variable and what the implications are of using either one in your code. That pretty much takes up a full hour. &lt;/p&gt;  &lt;p&gt;Second presentation, Loading Data in Real Time. It's really a presentation about partitioning but with a twist that we used at work recently to solve a need to load some data quickly and put it into production with minimal downtime. We'll cover partition functions, schemes,$partition, merge, sys.partitions and show some examples of building a set of partitioned tables and using the switch statement to move it from one table to another. Finally we'll cover the differences in partitioning between 2005 and 2008. Hope to see you there! &lt;/p&gt;  &lt;p&gt;And if you read my blog please introduce yourself!&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/mikef/aggbug/61127.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mike Femenella</dc:creator>
            <guid>http://weblogs.sqlteam.com/mikef/archive/2010/04/12/SQL-Saturday-Atlanta-Intro-To-Performance-Tuning.aspx</guid>
            <pubDate>Tue, 13 Apr 2010 01:00:06 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/mikef/archive/2010/04/12/SQL-Saturday-Atlanta-Intro-To-Performance-Tuning.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/mikef/comments/commentRss/61127.aspx</wfw:commentRss>
        </item>
        <item>
            <title>SQL Saturday Richmond, VA</title>
            <link>http://weblogs.sqlteam.com/mikef/archive/2010/03/27/SQL-Saturday-Richmond-VA.aspx</link>
            <description>&lt;p&gt;Very excited to announce that I’ll be holding 2 sessions at SQL Saturday in VA on April 10th. If there are any frequent readers of SQLTeam.com attending, please make sure to say hi! Topics I’m covering are partitioning &amp;amp; loading data real time and an introduction to performance tuning. Hope to see you there!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sqlsaturday.com/30/schedule.aspx" target="_blank"&gt;SQL Saturday Richmond Schedule&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/mikef/aggbug/61125.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mike</dc:creator>
            <guid>http://weblogs.sqlteam.com/mikef/archive/2010/03/27/SQL-Saturday-Richmond-VA.aspx</guid>
            <pubDate>Sun, 28 Mar 2010 00:19:31 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/mikef/archive/2010/03/27/SQL-Saturday-Richmond-VA.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/mikef/comments/commentRss/61125.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>