Using Temporary Tables in Stored Procedures


Temporary tables are commonly used in stored procedures when you need to store intermediate results in a work table for additional or more advanced processing. You need to keep a few things in mind when using temporary tables in stored procedures.

In versions of SQL Server prior to 7.0, if a subprocedure referenced a temporary table created externally, a temporary table with the same name and structure had to exist at the time the stored procedure was created. This is no longer the case now that SQL Server performs deferred name resolution. The existence of the temporary table is not checked until the stored procedure is executed.

Local temporary tables created in a stored procedure are automatically dropped when the stored procedure exits. Global temporary tables created in a stored procedure will still exist after the stored procedure exits until they are explicitly dropped (see Listing 28.22) or the user session in which they were created disconnects from SQL Server.

Listing 28.22 Using Local and Global Temporary Tables in Stored Procedures
 create proc temp_test2 as select * into ##temp from publishers select * into #temp from publishers go exec temp_test2 go select * from ##temp go pub_id pub_name                   city           state country ------ -------------------------- -------------- ----- ----------- 0736   New Moon Books             Boston         MA    USA 0877   Binnet & Hardley           Washington     DC    USA 1389   Algodata Infosystems       Berkeley       CA    USA 1622   Five Lakes Publishing      Chicago        IL    USA 1756   Ramona Publishers          Dallas         TX    USA 9901   GGG&G                      Mnchen        NULL  Germany 9952   Scootney Books             New York       NY    USA 9999   Lucerne Publishing         Paris          NULL  France select * from #temp go Server: Msg 208, Level 16, State 1, Line 1 Invalid object name '#temp'. 

Note what happens if you try to run the stored procedure again:

 exec temp_test2  go Server: Msg 2714, Level 16, State 6, Procedure temp_test2, Line 3 There is already an object named '##temp' in the database. 

TIP

Personally, I don't find much use for global temporary tables in stored procedures. The typical reason for using temporary tables in stored procedures is that you need a work area within the stored procedure only. You normally wouldn't want it sticking around after the procedure finishes. Creating a global temporary table in a stored procedure requires an explicit drop of the table before the procedure exits if you no longer need it. If that's the case, what's the benefit of using a global temporary table? Any subprocedures will be able to see and reference a local temporary table created in the calling procedure, so global temporary tables are not needed in that case.

Only if you need to create and populate a worktable and have it available after the procedure exits should you consider using a global temporary table. However, you would have to remember to explicitly drop it at some point before attempting to run the procedure again. However, if an error occurs that aborts processing of the stored procedure, the explicit drop might not be executed.

You might want to include a check for the global temporary table in your stored procedure and drop it automatically before attempting to create it again, as in the following code snippet:

[View full width]
 
[View full width]
create proc myproc as if exists (select 1 from tempdb..sysobjects where name = graphics/ccc.gif '##global_temp' and type = 'U') drop table ##global_Temp select * into ##global_temp from ...

Temporary Table Performance Tips

All users within SQL Server share the same tempdb database for work tables and temporary tables, regardless of the database in which they are working. This makes tempdb a potential bottleneck in any multiuser system. The primary bottleneck in tempdb is disk I/O, but locking contention can also exist between processes on the tempdb system tables.

SQL Server 2000 solves the disk I/O problem a bit by logging just enough information to allow rollback of transactions without logging all the additional information that would be necessary to recover those transactions. The recovery information is needed only when recovering a database at system startup or when restoring from a backup. Because tempdb is rebuilt during SQL Server startup (and no one in their right mind would restore tempdb from a backup), it's unnecessary to keep this recovery information. By reducing the logging in tempdb, data modification operations on tables in tempdb can be up to four times faster than the same operations in other databases.

On the other hand, locking in tempdb is still a potential performance bottleneck. If you create a table in tempdb within a transaction, locks are held on rows in the system tables sysobjects , syscolumns , and sysindexes related to the table created, as shown in Listing 28.23.

Listing 28.23 Locks Held on System Tables in tempdb When Creating a Temporary Table
 begin tran select * into #temptab from titles exec sp_lock go spid   dbid   ObjId       IndId  Type Resource         Mode     Status ------ ------ ----------- ------ ---- ---------------- -------- ------     51      2           0      0 DB   [BULK-OP-LOG]    NULL     GRANT     51      5           0      0 DB                    S        GRANT     51      2           0      0 DB   [BULK-OP-DB]     NULL     GRANT     51      2           1      0 TAB                   IX       GRANT     51      2           3      0 TAB                   IX       GRANT     51      2           2      0 TAB                   IX       GRANT     51      2           3      2 KEY  (bd018d280de1)   X        GRANT     51      2           3      2 KEY  (b101e50ba351)   X        GRANT     51      2           3      1 KEY  (080056b1859e)   X        GRANT     51      2           3      1 KEY  (0900b81e308c)   X        GRANT     51      2           3      1 KEY  (0e008aeeeebb)   X        GRANT     51      2           3      1 KEY  (0b0064415ba9)   X        GRANT     51      2           3      1 KEY  (0f00dcfe8de3)   X        GRANT     51      2           0      0 PAG  1:78             X        GRANT     51      2           0      0 PAG  1:77             X        GRANT     51      2           0      0 PAG  1:94             X        GRANT     51      2           0      0 PAG  1:95             X        GRANT     51      2           0      0 PAG  1:92             X        GRANT     51      2           0      0 PAG  1:93             X        GRANT     51      2           0      0 PAG  1:90             X        GRANT     51      2           0      0 PAG  1:91             X        GRANT     51      2           0      0 PAG  1:89             X        GRANT     51      2           0      0 EXT  1:104            X        GRANT     51      2           0      0 PAG  1:102            X        GRANT     51      2           0      0 PAG  1:103            X        GRANT     51      2           0      0 PAG  1:100            X        GRANT     51      2           0      0 PAG  1:101            X        GRANT     51      2           0      0 PAG  1:98             X        GRANT     51      2           0      0 PAG  1:99             X        GRANT     51      2           0      0 PAG  1:96             X        GRANT     51      2           0      0 PAG  1:97             X        GRANT     51      2           0      0 PAG  1:110            X        GRANT     51      2           0      0 EXT  1:96             X        GRANT     51      2           0      0 PAG  1:111            X        GRANT     51      2           0      0 PAG  1:108            X        GRANT     51      2           0      0 PAG  1:109            X        GRANT     51      2           0      0 PAG  1:106            X        GRANT     51      2           0      0 PAG  1:107            X        GRANT     51      2           0      0 PAG  1:104            X        GRANT     51      2           0      0 PAG  1:105            X        GRANT     51      2           0      0 PAG  1:118            X        GRANT     51      2           0      0 PAG  1:119            X        GRANT     51      2           0      0 PAG  1:116            X        GRANT     51      2           0      0 PAG  1:117            X        GRANT     51      2           0      0 PAG  1:114            X        GRANT     51      2           0      0 PAG  1:115            X        GRANT     51      2           0      0 PAG  1:112            X        GRANT     51      2           0      0 PAG  1:113            X        GRANT     51      2           0      0 EXT  1:112            X        GRANT     51      2           1      2 KEY  (8516877f1c72)   X        GRANT     51      2           0      0 IDX  IDX: 2:469576711 X        GRANT     51      2   469576711      0 TAB                   Sch-M    GRANT     51      2           3      2 KEY  (54016b2ccfff)   X        GRANT     51      2           1      3 KEY  (0700b7f12a1d)   X        GRANT     51      2           3      2 KEY  (4201380b1b46)   X        GRANT     51      1    85575343      0 TAB                   IS       GRANT     51      2           3      2 KEY  (5c013a008346)   X        GRANT     51      2           3      2 KEY  (9f01b84495cc)   X        GRANT     51      2           3      1 KEY  (110057368449)   X        GRANT     51      2           3      1 KEY  (1000b999315b)   X        GRANT     51      2           3      2 KEY  (eb002ad7df7e)   X        GRANT     51      2           3      1 KEY  (0a00dd798c34)   X        GRANT     51      2           3      1 KEY  (0d00ef895203)   X        GRANT     51      2           3      2 KEY  (36027a4d788e)   X        GRANT     51      2           3      1 KEY  (0c000126e711)   X        GRANT     51      2           1      1 KEY  (0700c2f14c59)   X        GRANT     51      2           2      1 KEY  (07000a2e7633)   X        GRANT     51      2           3      2 KEY  (450124fb6f35)   X        GRANT     51      2           3      2 KEY  (d7016cf8d9e5)   X        GRANT     52      5           0      0 DB                    S        GRANT     53      5           0      0 DB                    S        GRANT 

The tempdb database has a dbid of 2, and the sysobjects table has an object ID of 1; sysindexes is object ID 2, and syscolumns is object ID 3. These locks being held on the system tables could lead to locking contention with other processes trying to read or update the tempdb system catalogs.

To minimize the potential for locking contention on the system tables in tempdb , consider creating your temp tables before starting the transaction so that locks are released immediately and not held on the system catalogs until the end of the transaction. If the table must be created in a transaction, commit your transaction as soon as possible.

Also, be aware that even if it's not in a transaction, creating a temporary table using SELECT INTO will hold locks on the system catalogs in tempdb until the SELECT INTO completes. If locking contention in tempdb becomes a problem, consider replacing SELECT INTO with CREATE TABLE followed by an INSERT using a SELECT statement. Although this might run a bit more slowly than SELECT INTO , the system table locks are held only for the brief moment it takes for CREATE TABLE to complete.

Another way to speed up temp table creation/population is to keep temporary tables as small as possible so they create more quickly. Select only the required columns , rather than SELECT * , and only retrieve the rows that you need. The smaller the temporary table, the faster it will be to create the table as well as to access the table.

If the temp table is of sufficient size and is going to be accessed multiple times within a stored procedure, it might be cost effective to create an index on it on the column(s) that will be referenced in the search arguments of queries against the temp table. The deciding factor of whether to create an index on a temporary table is if the time it takes to create the index plus the time the queries take to run using the index is less than the sum total of the time it takes the queries against the temporary table to run without the index.

The following example demonstrates the creation of an index on a temporary table:

 use bigpubs2000  go create proc p1 WITH RECOMPILE as select title_id, type, pub_id, ytd_sales    into #temp_titles    from titles create index tmp on #temp_titles(pub_id) select sum(ytd_sales)    from #temp_titles    where pub_id = '0736' select min(ytd_sales)    from #temp_titles    where pub_id = '0736' return go 

Some other final tips when using temporary tables in stored procedures:

  • Don't use temp tables to combine resultsets together when a UNION or UNION ALL will suffice. UNION ALL will be the fastest because no work table in tempdb is required to merge the resultsets.

  • Drop temporary tables as soon as possible to free up space in tempdb .

  • Consider using the table datatype to avoid tempdb usage altogether.



Microsoft SQL Server 2000 Unleashed
Microsoft SQL Server 2000 Unleashed (2nd Edition)
ISBN: 0672324679
EAN: 2147483647
Year: 2002
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net