Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase 12»»

SELECT vs INSERT INTO Expand / Collapse
Author
Message
Posted Friday, January 11, 2013 12:34 PM
SSC Rookie

SSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC Rookie

Group: General Forum Members
Last Login: Friday, June 07, 2013 1:49 PM
Points: 36, Visits: 270
I've been searching for pointers on SELECT..INTO vs INSERT..INTO around forums and the web and haven't been successful yet. Basically, if you are using temp tables in a stored procedure is there a pros/cons of using SELECT something INTO #temptable versus explicitly defining the table and then using INSERT INTO #temptable? Is the answer affected by the number of rows, width of table, use of indexes on the temp tables, etc? Any advice or pointers to articles would be awesome.

Thanks for any direction.

Cliff



Post #1406231
Posted Friday, January 11, 2013 12:38 PM
Old Hand

Old HandOld HandOld HandOld HandOld HandOld HandOld HandOld Hand

Group: General Forum Members
Last Login: Yesterday @ 6:52 AM
Points: 324, Visits: 315
I believe that SELECT...INTO results in less impact on the transaction log. Also, if there are differences in collation between the db you're in and tempdb, SELECT...INTO will create a temporary table with the collation of the table you're selecting from, while creating the table using CREATE TABLE will use the collation of tempdb. Keep in mind that neither method will give any logical structure to your temporary table: remember to put a PK or clustered index on it, just as you would a permanent table.

Roland Alexander
The Developing World


There are two means of refuge from the miseries of life: music and cats. ~ Albert Schweitzer
Post #1406232
Posted Friday, January 11, 2013 12:57 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Yesterday @ 3:12 PM
Points: 8,957, Visits: 8,523
Also select into will throw an exception if the the destination table already exists. You do not have as much control over the datatypes when using a select into either, it will use the datatype from the source. That is not a bad thing but something to understand about how it works. For example if you have a varchar(10) but you know you will want to update the table after you insert your data and the new value will be longer you probably don't want to use select into. Neither approach is the right or the wrong answer. They both work just fine. There are implications of either approach that need to be considered when writing your code.

_______________________________________________________________

Need help? Help us help you.

Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

Need to split a string? Try Jeff Moden's splitter.

Cross Tabs and Pivots, Part 1 – Converting Rows to Columns
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs
Post #1406237
Posted Friday, January 11, 2013 1:03 PM
Old Hand

Old HandOld HandOld HandOld HandOld HandOld HandOld HandOld Hand

Group: General Forum Members
Last Login: Yesterday @ 6:52 AM
Points: 324, Visits: 315
Sean Lange (1/11/2013)
Also select into will throw an exception if the the destination table already exists. You do not have as much control over the datatypes when using a select into either, it will use the datatype from the source. That is not a bad thing but something to understand about how it works. For example if you have a varchar(10) but you know you will want to update the table after you insert your data and the new value will be longer you probably don't want to use select into. Neither approach is the right or the wrong answer. They both work just fine. There are implications of either approach that need to be considered when writing your code.


Good points! As to the destination table already existing, that shouldn't be a problem if you're selecting into a temp table. SQL Server will give it a unique name in the db even if you don't (i.e. you can create multiple instances of "#tmp" concurrently but each has a unique name in the system table).


Roland Alexander
The Developing World


There are two means of refuge from the miseries of life: music and cats. ~ Albert Schweitzer
Post #1406239
Posted Friday, January 11, 2013 1:12 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Yesterday @ 3:12 PM
Points: 8,957, Visits: 8,523
Roland Alexander STL (1/11/2013)
As to the destination table already existing, that shouldn't be a problem if you're selecting into a temp table. SQL Server will give it a unique name in the db even if you don't (i.e. you can create multiple instances of "#tmp" concurrently but each has a unique name in the system table).


That isn't true. If it was we would never be able to use them. It is also painlessly easy to prove.

select top 5 *
into #MyTable
from sys.objects

select top 5 *
into #MyTable
from sys.objects



--EDIT--

Now if the same temp table was in a different batch your statement is true.


_______________________________________________________________

Need help? Help us help you.

Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

Need to split a string? Try Jeff Moden's splitter.

Cross Tabs and Pivots, Part 1 – Converting Rows to Columns
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs
Post #1406243
Posted Friday, January 11, 2013 1:20 PM
Old Hand

Old HandOld HandOld HandOld HandOld HandOld HandOld HandOld Hand

Group: General Forum Members
Last Login: Yesterday @ 6:52 AM
Points: 324, Visits: 315
Sean Lange (1/11/2013)
Roland Alexander STL (1/11/2013)
As to the destination table already existing, that shouldn't be a problem if you're selecting into a temp table. SQL Server will give it a unique name in the db even if you don't (i.e. you can create multiple instances of "#tmp" concurrently but each has a unique name in the system table).


That isn't true. If it was we would never be able to use them. It is also painlessly easy to prove.

select top 5 *
into #MyTable
from sys.objects

select top 5 *
into #MyTable
from sys.objects



--EDIT--

Now if the same temp table was in a different batch your statement is true.


You're right, of course, and I should have made clear that by "concurrent" I meant "concurrent but separate connections": so that if you and I each have a connection and each execute the SP in question, there won't be any collisions. Thanks for the correction.


Roland Alexander
The Developing World


There are two means of refuge from the miseries of life: music and cats. ~ Albert Schweitzer
Post #1406244
Posted Friday, January 11, 2013 1:54 PM
SSC Rookie

SSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC RookieSSC Rookie

Group: General Forum Members
Last Login: Friday, June 07, 2013 1:49 PM
Points: 36, Visits: 270
Thanks for the great input. It was helpful.

Cliff



Post #1406252
Posted Saturday, January 12, 2013 9:01 PM


SSCertifiable

SSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiable

Group: General Forum Members
Last Login: Yesterday @ 1:24 PM
Points: 6,826, Visits: 11,950
Sean Lange (1/11/2013)
You do not have as much control over the datatypes when using a select into either, it will use the datatype from the source. That is not a bad thing but something to understand about how it works.

We can manipulate this behavior though. Say I have a column that is a NVARCHAR(128) and I want it to be a NVARCHAR(500) in my temp table if I cast that column in my SELECT-column-list SQL Server will honor the casted datatype when the temp table is created, e.g.

SELECT  object_id,
CAST(name AS NVARCHAR(500)) AS name
INTO #TempTable
FROM sys.tables;



__________________________________________________________________________________________________
There are no special teachers of virtue, because virtue is taught by the whole community. --Plato

Believe you can and you're halfway there. --Theodore Roosevelt

Everything Should Be Made as Simple as Possible, But Not Simpler --Albert Einstein

The significant problems we face cannot be solved at the same level of thinking we were at when we created them. --Albert Einstein

1 apple is not exactly 1/8 of 8 apples. Because there are no absolutely identical apples. --Giordy
Post #1406442
Posted Monday, January 14, 2013 1:28 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Thursday, June 13, 2013 7:03 AM
Points: 2,562, Visits: 3,453
i think "insert into select " provide better readabilty when we use this approach in "long time used queries/stored proc". we can easily see what are the columns and what kind of data we are going to store ? .Easy to troubleshoot.

-------Bhuvnesh----------
While 1 = 1 (Learning SQL....)
Click to get fast response of your post
Post #1406590
Posted Monday, January 14, 2013 10:05 AM
SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC Veteran

Group: General Forum Members
Last Login: Yesterday @ 5:43 PM
Points: 298, Visits: 1,320
Bhuvnesh (1/14/2013)
i think "insert into select " provide better readabilty when we use this approach in "long time used queries/stored proc". we can easily see what are the columns and what kind of data we are going to store ? .Easy to troubleshoot.

I agree with this. Explicitly creating the table and doing an "INSERT INTO SELECT [...]" is self-documenting and when you have to go back and look at the code a year later you will know the data structure of the temp table without having to do a lot of digging into the procedure. Creating the table first also enforces a bit of discipline by forcing the developer to think about what data is going to be handled by a procedure (as opposed to the dynamic SELECT INTO approach).

Also, as someone mentioned above, it's important to have a primary key even on a temp table and in my experience I've found that inexperienced developers tend to use SELECT INTO because it's "easier" and wind up creating a heap because they just don't know any better. For my shop I have a standard to use for temp tables and on my own workstation I have a hot key for the RedGate snippet manager that inserts a template on demand:


IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable

CREATE TABLE #TempTable (
[ID] INT IDENTITY(1,1) NOT NULL,
[Col1] INT NULL,
[Col2] NVARCHAR(50) NULL,
PRIMARY KEY (ID))

INSERT INTO #TempTable
SELECT
Col1
,Col2
FROM
dbo.TableName
WHERE
1 = 1


Another issue to consider is recompilation. Mixing DDL and DML within a procedure can cause recompilation. In the code snippet above the DDL "CREATE TABLE" comes prior to the DML "INSERT INTO". But using "SELECT INTO" in the wrong order can cause recompilation every time a procedure is run. The procedure should be tested to make sure recompilation is not occurring. (See Optimizing SQL Server Stored Procedures to Avoid Recompiles and Troubleshooting stored procedure recompilation.)

A final note to consider is the creation of indexes on a temp table. As you can see in the snippet example above, SQL will create it's own uniquely-named PK when the table is created. However, if a primary key or index is added after the temp table is created there is no guarantee that the name of the key or index will be unique. This can cause an error if the procedure is creating a temp table dynamically for one user and then tries to create the "same" temp table for a different instance of the procedure because the names of the keys or indexes may already exist.

When explicitly creating a temp table with the Primary Key attribute the PK will be named something like this:

[PK__#TempTable__3214EC27582F7143]

Every time the procedure is called, it will create a unique temp table object and PK. If a temp table is created like below a unique PK will also be created:


SELECT ProductID, CategoryID
INTO #TempTable
FROM dbo.Products

ALTER TABLE dbo.Products ADD PRIMARY KEY(ProductID)


Though in my experience it's rarely needed, if for some reason additional keys are deemed necessary for a temp table care must be taken to make sure the keys have unique names. For example:


DECLARE
@strCreateIndex NVARCHAR(1000)
,@IndexUniqueID NVARCHAR(50)

SET @IndexUniqueID = N'IX__#TempTable__'+REPLACE(CAST(NEWID() AS NVARCHAR(50)),'-','')
SET @strCreateIndex =
N'CREATE NONCLUSTERED INDEX [' + @IndexUniqueID + '] ON [#TempTable] ([ProductID])'

EXEC sp_executesql @strCreateIndex


Post #1406826
« Prev Topic | Next Topic »

Add to briefcase 12»»

Permissions Expand / Collapse