Auto update statistics threshold of temp table in stored procedure

The threshold of temp table in stored procedure is little bit tricky, it doesn’t exactly follow the regular threshold.

First of all, you can’t use the modification_counter to determine when auto update statistics happens. Because the data in tempdb is deleted every time after execution, replying on the data that that already deleted is pointless.

Secondly, the algorithm is different:

Here is the original threshold of temp table that are not in stored procedure.

thumbnail image 1 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

Here is the new algorithm. (note, compatibility of user database decides old threshold or sublinear threshold, the compatibility of tempdb does not matter)

Table cardinality (n)

Old threshold

Sublinear threshold

n < 6

>=n+6

>=n+6

6 <= n <= 500

>=n+500

>=n+500

500<n <=19682

>= n+(500 +0.2*n)

or

<= n-(500+0.2*n)

>= n+(500 +0.2*n)

or

<= n-(500+0.2*n)

n >19682

500 + (0.20 * n)

>= n+sqrt(1000*n)

or

<=n-sqrt(1000*n)

 

 

Here is an example in compatibility level 150 in SQL 2019.

1.Enable the AUTO_update_STATISTICS for temp table and create a table with 30,000 rows.

alter database tempdb set AUTO_update_STATISTICS on--

go

use dbstat

go

create table table1(c1 int,c2 int,c3 int)

------------ --------INSERT 30,000 rows to table table1

go

with cte

as

(

   select top 30000 ROW_NUMBER() over(order by c.object_id) id from sys.columns c cross join sys.all_objects

)

insert table1

select id,id,id from cte

go

 

2.Create a stored procedure. In this stored procedure, it imports the data from table1 created in step1, into the temp table #t1, then run select query against the temp table #t1

create proc procTempTable

@num int

as

create table #t1(c1 int index ic nonclustered,c2 int,c3 int)---create temp table with primary key

insert #t1 select top(@num) * from table1 order by c1---insert data to temp table

select * from #t1  where c1=@num

select object_id('tempdb.dbo.#t1') as TableId

3.Let’s run the stored procedure which parameter 2.

exec procTempTable 2

thumbnail image 2 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

4.Here is what happened when the stored procedure is created the first time.

1)The temp table #t1 is created, and it will be cached for reuse until the stored procedure gets recompiled.

If you’re not familiar with the temp table caching, please refer Paul White’s article.

2)Because index ic on column1 is specified inline in the create table DDL, a statistics with same name is created at the same time when table #t1 is created.

3)The statistics is refreshed when following query is executed.

select * from #t1 where c1=@num

 

4).Here is the statistics info

use tempdb

go

select sp.*From sys.stats s cross apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp  where s.object_id=-1242610934

thumbnail image 3 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

4.For temp table that are not in stored procedure, the statistics is updated after the threshold is reached and a query running against the statistics.

But it’s totally different if the temp table is in stored procedure, the threshold does not depend on the modification_counter, which is a cumulative value.

For example, I run the stored procedure 200 times, the modification_counter increase to 1002, but update statistics will not happen.

exec procTempTable 2

go 200

thumbnail image 4 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

To trigger the auto update statistics, the number of row change has before the temp table is deleted in single execution has to reach the threshold.

In this case, the cardinality is 2, the threshold is n+6=2+6=8.

Running following t-sql will trigger the auto update statistics.

use dbstat

go

exec procTempTable 8

thumbnail image 5 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

thumbnail image 6 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

N<500

Now the cardinality of temp table becomes 8, the threshold become n+500=508 according to the formula.

Running following t-sql will trigger the auto update statistics.

use dbstat

go

exec procTempTable 508

thumbnail image 7 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

thumbnail image 8 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

 

500<n<=19682

a)According to the formula:

the number of data change is >= n+(500 +0.2*n)=508+(500+508*0.2)=1109

or

the number of data change is <= n-(500 +0.2*n)=508-(500+508*0.2)= -93,which is not possible

exec procTempTable 1109

thumbnail image 9 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

thumbnail image 10 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

b)1109 is still less than 19682, According to the formula:

the number of data change is >= n+(500 +0.2*n)= 1109+(500+1109*0.2)= 1830

or

the number of data change is <= n-(500 +0.2*n)= 1109-(500+1109*0.2)= 388.

Let’s use 388 this time.

exec procTempTable 388

thumbnail image 11 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

thumbnail image 12 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

n>19682

Now we have 20,000 rows by running the exec procTempTable 20000

thumbnail image 13 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

The threshold is

>= n+sqrt(1000*n)= 20000+sqrt(1000*20000) = 24472

or

 <= n-sqrt(1000*n)= 20000- sqrt(1000*20000) = 15528.

 

thumbnail image 14 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

thumbnail image 15 of blog post titled 
	
	
	 
	
	
	
				
		
			
				
						
							Auto update statistics threshold of temp table in stored procedure

 

 

Comments

popular posts

SQL Server Polybase in Failover cluster instance

Tutorial: Create SQL Cluster(FCI) on RHEL

Configure multiple-subnet Always On Availability Groups and failover cluster instances by modifying CIB

Realcase: Failed to upgrade SQL Server 2016 SP2 CU11. (Installation success or error status: 1648)

How to find SQL Server Replication related jobs and T-SQL statements

SQL Server Extents, PFS, GAM, SGAM and IAM and related corruptions

Tutorial: Add a node to SQL cluster on RHEL

Password is required when adding a database to AG group if the database has a master key

You may fail to backup log or restore log after TDE certification/key rotation

SQL Server GAM corruption samples