Best practices for the SQL Server TempDB

SQL Server Error logs not optimally configured.

What is the TempDB database?

Tempdb is one of the system databases in Microsoft SQL Server.

It’s a global resource that holds temporary user objects, row versioning information and internal objects that are created by the SQL Server engine.

SQL Server creates a clean copy of the TempDB every time the instance is started.

By the way, this check is a part of our SQL Server Health Check service.

Why should you care about it?

Tempdb affects the performance of all SQL Server.

Many background processes use TempDB.

If it does not perform optimally, all databases are affected and will slow the whole server down.

How to adjust TempDB for the best performance?

– Check the number of data files

SQL Server by default configuration has a single data file for TempDB.

Microsoft’s best practices recommend Increase the number of data files to maximize disk bandwidth and reduce contention.

You can use the script below to verify and generate the change script for your server.

  1. Change the variable @check to 1 to implement the change. The default value 0 only shows the information.
  1. DECLARE @check BIT
  2.  
  3. SET @check = 0 --For information set 0, for change 1
  4.  
  5. DECLARE @BASEPATH NVARCHAR(300)
  6. DECLARE @SQL_SCRIPT NVARCHAR(1000)
  7. DECLARE @CORES INT
  8. DECLARE @FILECOUNT INT
  9. DECLARE @SIZE INT
  10. DECLARE @GROWTH INT
  11. DECLARE @ISPERCENT INT
  12.  
  13. -- TempDB mdf count equal logical cpu count
  14. SELECT @CORES = cpu_count FROM sys.dm_os_sys_info
  15.  
  16. PRINT 'Logical CPU count ' + CAST(@CORES AS NVARCHAR(100))
  17.  
  18. IF @CORES BETWEEN 9 AND 31 SET @CORES = @CORES / 2
  19. IF @CORES >= 32 SET @CORES = @CORES / 4
  20.  
  21. --Check and set tempdb files count are multiples of 4
  22. IF @CORES > 8 SET @CORES = @CORES - (@CORES % 4)
  23.  
  24. SET @BASEPATH = (SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'tempdb.mdf', LOWER(physical_name)) - 1) DataFileLocation
  25. FROM master.sys.master_files
  26. WHERE database_id = 2 AND FILE_ID = 1)
  27.  
  28. SET @FILECOUNT = (SELECT COUNT(*)
  29. FROM master.sys.master_files
  30. WHERE database_id = 2 AND TYPE_DESC = N'ROWS')
  31.  
  32. SELECT @SIZE = size FROM master.sys.master_files WHERE database_id = 2 AND FILE_ID = 1
  33. SET @SIZE = @SIZE / 128
  34.  
  35. SELECT @GROWTH = growth FROM master.sys.master_files WHERE database_id = 2 AND FILE_ID = 1
  36. SELECT @ISPERCENT = is_percent_growth FROM master.sys.master_files WHERE database_id = 2 AND FILE_ID = 1
  37.  
  38. IF @ISPERCENT = 0 SET @GROWTH = @GROWTH * 8
  39.  
  40. --Current situation
  41. PRINT 'Needed ' + CAST(@CORES AS NVARCHAR(100)) + ' TempDB data files, now there is ' + CAST(@FILECOUNT AS NVARCHAR(100)) + CHAR(10) + CHAR(13)
  42.  
  43. IF @check = 1 AND @CORES > @FILECOUNT PRINT 'Commands listed below will be executed' + CHAR(10) + CHAR(13)
  44. IF @check = 0 AND @CORES > @FILECOUNT PRINT 'Commands listed below will NOT be executed' + CHAR(10) + CHAR(13)
  45.  
  46. WHILE @CORES > @FILECOUNT
  47. BEGIN
  48.                 SET @SQL_SCRIPT = N'ALTER DATABASE tempdb
  49.                 ADD FILE (
  50.                                FILENAME = ''' + @BASEPATH + 'tempdb' + RTRIM(CAST(@CORES AS NCHAR)) + '.ndf'',
  51.                                NAME = tempdev' + RTRIM(CAST(@CORES AS NCHAR)) + ',
  52.                                SIZE = ' + RTRIM(CAST(@SIZE AS NCHAR)) + 'MB,
  53.                                FILEGROWTH = ' + RTRIM(CAST(@GROWTH AS NCHAR))
  54.                 IF @ISPERCENT = 1 SET @SQL_SCRIPT = @SQL_SCRIPT + '%' ELSE SET @SQL_SCRIPT = @SQL_SCRIPT + 'KB'         
  55.                 SET @SQL_SCRIPT = @SQL_SCRIPT + ')'
  56.                 IF @check = 1 EXEC(@SQL_SCRIPT)      
  57.                 PRINT @SQL_SCRIPT
  58.                 SET @CORES = @CORES - 1
  59. END

Note: SQL Server 2016 has a built-in feature that detects the number of CPU cores and automatically creates the appropriate amount of TempDB data files.

– Review the size and autogrow settings

Set a right size (you can start with 10GB) and adjust the autogrow settings to a fixed value. Here is a post on how to change autogrowth settings.

Don’t use percentages.

– Use a dedicated Hard disk drive

Most high-performance SQL servers place tempdb on a dedicated disk drive.

Do that if you can.

– Use trace flags T1117 & T1118

They will helps tempdb perform faster. Check out our post about trace flags.

Note: Microsoft made this behavior standard in SQL Server 2016 and newer versions.

More information

Recommendations to reduce allocation contention in SQL Server tempdb
Working with tempdb in SQL Server 2005
Concurrency enhancements for the tempdb database

Mark Varnas

Mark Varnas

Hey I'm Mark, one of the guys behind Red9. I make a living performance tuning SQL Servers and making them more stable. I channel my SQL into our SQL Managed Services, SQL Consulting and our internal database products.

2 Responses

  1. I have executed above scripts but getting below error. Can you please help or send me the updated scripts.

    Msg 4145, Level 15, State 1, Line 19
    An expression of non-boolean type specified in a context where a condition is expected, near ‘;’.
    Msg 102, Level 15, State 1, Line 22
    Incorrect syntax near ‘;’.
    Msg 4145, Level 15, State 1, Line 43
    An expression of non-boolean type specified in a context where a condition is expected, near ‘;’.
    Msg 4145, Level 15, State 1, Line 44
    An expression of non-boolean type specified in a context where a condition is expected, near ‘;’.
    Msg 4145, Level 15, State 1, Line 46
    An expression of non-boolean type specified in a context where a condition is expected, near ‘;’.
    Msg 102, Level 15, State 1, Line 58
    Incorrect syntax near ‘1’.

Leave a Reply

Your email address will not be published. Required fields are marked *