The other day while studying I had the need to create a table and populate it with a small set of random data. I just so happened to have “Show Actual Execution Plan” enabled and when I executed the insert statement to populate the table (using a UNION SELECT) I was quite shocked at the plan generated.
This got me thinking that there must be a better, more efficient way to populate a table with data.
The set-up:
The set-up here is very basic. I wanted to test an insert into a table that had a clustered index (so we can see the effect of the insert which needed to update the index). I didn’t care what the values were or what the index was for the purpose of this test.
Create a test table:
USE tempdb
GO
CREATE TABLE tempvalues (
Value1 NUMERIC(5,5)
,Value2 NUMERIC(5,5)
,Value3 NUMERIC(5,5)
,CONSTRAINT [PK_tempvalues] PRIMARY KEY CLUSTERED (Value1, Value2, Value3));
GO
Insert some data using UNION SELECT
INSERT INTO tempdb..tempvalues (Value1, Value2, Value3)
SELECT 0.13601, 0.11622, 0.40041
UNION SELECT 0.28688, 0.33935, 0.58548
UNION SELECT 0.66694, 0.78595, 0.458
UNION SELECT 0.18889, 0.34067, 0.75255;
Here is the execution plan using a UNION SELECT:

As you can see there is a “Constant scan” operator for each row you are inserting. Now suppose you are doing this for 500 rows. Here is a partial extract of what the execution plan would look like:

As you can see there are now 500 “Constant Scan” operators which has flooded the graphical execution plan!
As we are working with such a small dataset, a more preferable way to do this kind of insert would be to use a Table Value Constructor (TVC).
What is a TVC?
Specifies a set of row value expressions to be constructed into a table. The Transact-SQL table value constructor allows multiple rows of data to be specified in a single DML statement. The table value constructor can be specified in the VALUES clause of the INSERT statement, in the USING <source table> clause of the MERGE statement, and in the definition of a derived table in the FROM clause.
Source: http://msdn.microsoft.com/en-us/library/dd776382(v=sql.105).aspx
Where would you use a TVC?
When constructing a static data set for insertion or selection. E.G. Reference data scripts.
Notable Limitations?
You can only specify a maximum of 1000 rows in a TVC.
TVC Syntax:
INSERT INTO tempdb..tempvalues (Value1, Value2, Value3)
SELECT Value1
,Value2
,Value3
FROM (
VALUES (0.13601,0.11622,0.40041)
,(0.28688,0.33935,0.58548)
,(0.66694,0.78595,0.458)
,(0.18889,0.34067,0.75255)
) AS x (Value1, Value2, Value3)
Here is what the execution plan looks like:

And even with 500 rows, the execution plan is the same:

Here are some stats to show the efficiency different between the 2 methods:
UNION SELECT (Inserting 500 rows)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 468 ms, elapsed time = 483 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table ‘tempvalues’. Scan count 0, logical reads 1005, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(500 row(s) affected)
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 78 ms, elapsed time = 140 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table Value Constructor (inserting 500 rows)
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 116 ms, elapsed time = 116 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table ‘tempvalues’. Scan count 0, logical reads 1005, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(500 row(s) affected)
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 18 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Summary:
It seems conclusive that using the TVC to insert small datasets (<1000 rows) is more efficient than using the UNION SELECT. Aside from having less processor and execution time it’s worth noting that the subtree cost and cached plan size would be smaller too.
At the end of the day any performance gain is worth it right?…
FINALLY!! After much anticipation Microsoft have finally introduced code snippets into the latest version of SQL Server.
How much time does one spend writing out the same code over and over to create objects or how much time is spent fixing errors made by copy and paste!
Code snippets eliminates these problems and creating them is simple.
Where are they located?
Code Snippets are in 2 locations.
If you create your own the default save location will be in the Customer Snippets directory but it is very possible to edit and/or add to the Default Snippets.
Snippets have a file extension of .SNIPPET but are simple XML files.
General XML layout.
locDefinitions / locTag - Title, Description, Author, Tool-tip. These will be displayed in the code snippets manager and in the snippets selection list



Next are the Literals - these are pretty much variables which can be used in the CDATA part of the file. The format of a Literal is:

These literals are then used to build the SQL statement:

Note that the Literals start and end with the $ symbol.
This will produce the following output:

Notice the pop-up when hovering the cursor over the data type.
It seems that one of the main purposes with using Literals are the ability to tab through them. As you can see from the above image, each Literal is highlighted yellow showing that they are tabbable. Unfortunately if you use the same Literal multiple times throughout your script you can only tab the first one. Tabbing order is defined by first literal in the script to the last. Pressing the “Enter” key will accept the changes to the Literals and the ability to tab will end.
Creating your own Snippets
The above is the basic layout of the .SNIPPET file, creating your own is easy, either create a new text file in a new folder (see below for creating a new folder) or an existing folder, fill out the Title, description etc, define any literals and fill out the CDATA. Rremember to save the file as .SNIPPET. If you are not creating the new file under an existing directory under the 1033 folder then you will need to open the Snippets Manager and “Import” your new snippet file. When importing your snippet file you will get the option to select an existing folder to save it in.
It’s worth noting that if you are creating your own files under an existing folder then once the file is added to the folder (and it’s valid) then the file will immediately be available to use.
Taking code snippets one step further
Code snippets are great as they are but its possible to make them even better by using parameters. Parameters are not new, they are used in SQL templates. Pressing Shift+CTRL+M will bring up the “Specify Values for Template Parameters” box where you can quickly fill out the templates parameters which can save huge amounts of time!
The general syntax for a parameter is:
<Parameter Name, Type, Value>
e.g.
<Table Name, sysname, Enter the name of the table>
This would appear as so:

Its possible to use this parameter format in the CDATA when building your SQL statement. Although it’s not exactly eye friendly, it makes filling out your snippets easier then ever !
Here’s one example of one of my Stored Procedure:

By using these parameters I can easily fill out the most boring parts of my stored procedure in under a minute leaving just the nice meaty stuff left to do.
Adding folders to the Snippet Menu:
To add a new folder to the snippet menu simply reference it in the SnippetsIndex.xml file.
Add a new SnippetDir to the language element.
<SnippetDir>
<OnOff>On</OnOff>
<Installed>true</Installed>
<Locale>LOCALE_ID</Locale>
<DirPath>%InstallRoot%\VSTSDB\Snippets\%LCID%\Name of the folder</DirPath>
<LocalizedName>Name of the folder</LocalizedName>
<SnippetDir>
Once added, create a folder of the same name in the root of the 1033 folder.
Next open the Code Snippets Manager and add the newly created folder. This will also import any files under the folder.
And there you have it! Creating your own SQL 11 Code Snippets.
Visual Studio 2010 has a whole host of features for database projects including a nice feature called “Data Generator”.
Data Generator basically does what it says on the tin… It generates sample data, as per this link http://msdn.microsoft.com/en-us/library/aa833267.aspx
What I want to achieve:
I want to be able to place some sample data that has some sort of valid postcode (valid in the sense of either 2 letters 1 number 1 number 2 letters OR 2 letters 2 numbers 2 numbers 2 letters). I don’t particularly care if the postcodes are valid UK ones or even exist for the purpose of this.
As part of the above MSDN link there is a SQL script which is used to create a sample database “DinnerNowDataGenerator”. The table “Restaurant” is what I used to test my Regular Expression.
If you have been following the MSDN post you will eventually get to the Data Generation Designer Screen:
Highlight the PostCode column and change the Generator properties to “Regular Expression”. Then in the properties of the PostCode column enter ([A-Z]{2}[0-9]{1,2})([0-9]{1}[A-Z]{2}) as the Expression. This will choose 2 random letters between A-Z, 1 or 2 random numbers between 0-9, 1 random number between 0-9 and 2 letters between A-Z.