March 5, 2008 at 7:00 am
Is using too many temporary tables (#Temp..) in an SP, a bad practice by any chance? Or does it hamper performance?
I have an SP that imports records from over 5 Access tables through a linked server.
I use several temporary tables to store these records prior to insertion in SQL as I need to perform data validation and also various calculations for number of eligible, imported and not imported records.
Seems like my SP takes over 1.5 mins to execute.
But then again there is this table in Access with a million records, and simply reading and retrieving required records from it in a single query in SSMS takes a while.
March 5, 2008 at 7:12 am
It's not hard & fast or black & white. In general terms, using a temp table is not bad. It depends on what you're doing with it and how it's used. For example, one of the classic problematic uses of temp tables is to run a select statement against a table to populate a temp table then to run a series of updates against that temp table from various other tables. What this is doing is using the temp table in place of a join or joins. That's bad. An example of, what I think anyway, of a good use of temp tables... Back in 2000, before we had XPath queries, OPENXML was how we had to get XML data into the database. We had a series of batch inserts we wanted to do. We would load the XML into a temp tables and then close the XML document as fast as possible, then do the data loads from the temp tables (no updates to the temp tables after loading them). It worked well because it closed out the memory allocation for the XML faster at the cost of some I/O to load the temp tables.
So it can go either way. How are you using yours?
"The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
- Theodore Roosevelt
Author of:
SQL Server Execution Plans
SQL Server Query Performance Tuning
March 5, 2008 at 8:13 am
Also the configuration of tempdb database may have impact on performance of temp tables. If you have 1 million records, you should create indexes on these temp tables on fields you use to identify records.
Width of the table is another question - maybe you could shorten or drop some columns you don't use.
Piotr
...and your only reply is slàinte mhath
March 6, 2008 at 4:40 am
Grant Fritchey (3/5/2008)
What this is doing is using the temp table in place of a join or joins. That's bad.
True, I couldn't agree more.
Grant Fritchey (3/5/2008)
It depends on what you're doing with it and how it's used.How are you using yours?
I'm simply using my temp tables to hold data until I'm done validating, calculating and creating new records in new temp tables. All temp tables load data into different SQL tables.
There's just one place where I have to perform an update on a temp table, but that isn't in place of a join.. I have to generate a WorkOrderNumber for each record based on certain calculations (depending on the type of task and already existing nos. in Access and SQL), so this is something I do after loading the temp table.
What do you think?
March 6, 2008 at 4:58 am
Piotr Rodak (3/5/2008)
Also the configuration of tempdb database may have impact on performance of temp tables.
How do I check the configuration of tempdb? What should I be looking at, Piotr?
Piotr Rodak (3/5/2008)
If you have 1 million records, you should create indexes on these temp tables on fields you use to identify records.
Now, I'm simply doing a SELECT * INTO #Temp FROM...
Are you suggesting I first create these temp tables with indexes prior to loading them?
Could you tell me some more about how I should create my indexes? I'm not too familiar with all this! :ermm:
Piotr Rodak (3/5/2008)
Width of the table is another question - maybe you could shorten or drop some columns you don't use.
I've been thinking about this..
What I'm wondering is... if I say
--HERE I'M SELECTING ALL COLUMNS
SELECT * FROM LinkedServer...Locations
--HERE I'M SELECTING ALL 51 COLUMNS, SAME AS ABOVE
SELECT Column1,
,Column2
,Column3
, ......
.
.
,Column51
FROM LinkedServer...Locations
--HERE I'M SELECTING ONLY REQUIRED 31 COLUMNS
Select Column1
,Column2
,Column8
,Column15
,Collumn22
.
.
,Column39
.
.
,Column51
FROM LinkedServer...Locations
Will there be a significant difference in execution time in the above queries? There are 5 memo fields I'm selecting here from the Access table.
March 6, 2008 at 5:17 am
Grant Fritchey (3/5/2008)
What this is doing is using the temp table in place of a join or joins. That's bad.
Ummm... I gotta say, "Not always". I've used temp tables in the exact fashion you described to break up monsterous single SELECTs with multiple "haywire" joins in a "Divide and Conquer" fashion. The end result was that I was able to convert, for example, a 30 minute run into a 6 second run... and, no, that's not a type-o. 🙂
--Jeff Moden
Change is inevitable... Change for the better is not.
March 6, 2008 at 5:18 am
Nisha (3/6/2008)
Now, I'm simply doing a SELECT * INTO #Temp FROM...
Whoa! Don't do that - SELECT... INTO... on a temp table needs a schema lock to create the temp table and holds it for the duration of the insert. Best practice is to manually CREATE your temp table first then INSERT into it seperately. Otherwise you may find you're blocking out other TempDB users (eg most SPIDs) while you insert...
Nisha (3/6/2008)
I've been thinking about this..What I'm wondering is... if I say
--HERE I'M SELECTING ALL COLUMNS
SELECT * FROM LinkedServer...Locations
--HERE I'M SELECTING ALL 51 COLUMNS, SAME AS ABOVE
...
-snip-
...
Will there be a significant difference in execution time in the above queries? There are 5 memo fields I'm selecting here from the Access table.
Can't say whether there will be a significant difference, however there will be a difference. If you don't need the extra columns don't select them. You will be pulling less data from the Access DB and causing less pages to be used on the SQL side.
Regards,
Jacob
March 6, 2008 at 5:23 am
Jacob Luebbers (3/6/2008)
Nisha (3/6/2008)
Now, I'm simply doing a SELECT * INTO #Temp FROM...Whoa! Don't do that - SELECT... INTO... on a temp table needs a schema lock to create the temp table and holds it for the duration of the insert. Best practice is to manually CREATE your temp table first then INSERT into it seperately. Otherwise you may find you're blocking out other TempDB users (eg most SPIDs) while you insert...
Nisha (3/6/2008)
I've been thinking about this..What I'm wondering is... if I say
--HERE I'M SELECTING ALL COLUMNS
SELECT * FROM LinkedServer...Locations
--HERE I'M SELECTING ALL 51 COLUMNS, SAME AS ABOVE
...
-snip-
...
Will there be a significant difference in execution time in the above queries? There are 5 memo fields I'm selecting here from the Access table.
Can't say whether there will be a significant difference, however there will be a difference. If you don't need the extra columns don't select them. You will be pulling less data from the Access DB and causing less pages to be used on the SQL side.
Regards,
Jacob
Actually - select...into locks the schema so very little time - I honestly doubt you'd notice. On the other hand - select...INTO does seem to have a SUBSTANTIAL performance improvement over INSERT (like 25-30%). Quite honestly - well worth it in my book.
----------------------------------------------------------------------------------
Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?
March 6, 2008 at 5:32 am
To be honest I've never actually measured it myself, just heard it quoted in a number of sources as a bad practice and I've always studiously avoided it. Do you know if you get the same 25-30% performance boost on a plain INSERT with a schema lock hint?
I'd argue that you'd only be better off using a SELECT... INTO... onto a temp table if it happens very infrequently. Even if you only hold the schema lock for a short duration it still is effectively a critical section on a very "hot" resource (TempDB). Or if you really need that extra speed from SELECT... INTO... do it into a permanent table in a different DB.
Regards,
Jacob
March 6, 2008 at 6:11 am
Also, on the SELECT...INTO vs. CREATE TABLE & SELECT question. That one depends too. It depends on whether or not you are going to create indexes or in any other way perform a DDL operation on the temporary table. If you do, you may get recompiles on the procedure. That will kill performance for sure (depending on the size of the query, etc.).
"The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
- Theodore Roosevelt
Author of:
SQL Server Execution Plans
SQL Server Query Performance Tuning
March 6, 2008 at 6:24 am
SELECT/INTO hauls butt in any DB but it runs like an ape that sat on a hot coal if you use it on a database that is setup for anything other than FULL recovery. And, guess what... TempDB is setup for SIMPLE recovery.
Here's something for you to test with. For tables in TempDB, it'll do a million rows in just over 5 seconds... 10,000 rows almost doesn't show up on the radar. Should you do that many rows for high hit ratio GUI code? Probably not... but, for batch code, you can't beat SELECT/INTO and it runs so fast, you really don't have to worry that much about it taking a lock on Sys.Objects in TempDB...
[font="Courier New"]SET STATISTICS TIME ON
 SELECT TOP 10000 --Change this number to change the test
        IDENTITY(INT,1,1) AS N,
        sc1.ID AS sc1ID, sc1.Xtype AS XType1,
        sc2.ID AS sc2ID, sc2.Xtype AS Xtype2
   INTO #MyHead
   FROM Master.dbo.SysColumns sc1,
        Master.dbo.SysColumns sc2
DROP TABLE #MyHead[/font]
--Jeff Moden
Change is inevitable... Change for the better is not.
March 6, 2008 at 6:26 am
Jacob
Whoa! Don't do that - SELECT... INTO... on a temp table needs a schema lock to create the temp table and holds it for the duration of the insert. Best practice is to manually CREATE your temp table first then INSERT into it seperately. Otherwise you may find you're blocking out other TempDB users (eg most SPIDs) while you insert...
Matt
Actually - select...into locks the schema so very little time - I honestly doubt you'd notice. On the other hand - select...INTO does seem to have a SUBSTANTIAL performance improvement over INSERT (like 25-30%). Quite honestly - well worth it in my book.
Ok guys... I'm confused! What should I be doing now? Again.. I have PLENTY of temp tables in my SP.. THIRTY in number! And various operations performed on these throughout the 1600 lines of code.
March 6, 2008 at 6:29 am
Nisha, it depends... is the code for high hit ratio GUI code or is it for batch code that runs every once in a while?
--Jeff Moden
Change is inevitable... Change for the better is not.
March 6, 2008 at 7:09 am
Jeff Moden (3/6/2008)
Nisha, it depends... is the code for high hit ratio GUI code or is it for batch code that runs every once in a while?
Ooh.. sorry.. seems like we posted replies around the same time so I missed out reading your previous reply.
Ok.. I'm not entirely sure I understand what you mean by 'high hit ratio GUI code, Jeff :ermm:
There's an Import process triggered by 'ExportToSQL' Button on Legacy system (Access) that does a batch import of all WorkOrders for selected Contract, along with corresponding Locations, Providers, Installers, and so on.... the work orders could be in the range of 0-2000 in number during the import.
Does that make sense? :blink:
EDIT:
Ok, the import could happen over and over again in the same day or maybe once every few days... depending on the client's need. Like, whether he has new WorkOrders to push into SQL or not.
March 6, 2008 at 7:09 am
Interesting Jeff - just compared your test query (1m rows) with slightly modified version that CREATEs #MyHead first and INSERTs into it (both running in TempDB). This is on a busy server so times are inaccurate, however:
SELECT... INTO... < 5 s
CREATE... INSERT... > 10 s
Adding a TABLOCK hint on the second version didn't sem to help the runtime measurably. Can you (or anyone else) comment on the reasons for this difference?
To your last comment - 100% agree given these results. The answer to "should I use SELECT... INTO... or CREATE... INSERT... will depending on the frequency of execution rather than a hard and fast rule.
Regards,
Jacob
Viewing 15 posts - 1 through 15 (of 27 total)
You must be logged in to reply to this topic. Login to reply