Temporary tables are stored in the SQL Server database defined, it really necessary to explicitly delete (drop table #tableName) do?

 

Reprinted from: http://www.cnblogs.com/wy123/p/6704619.html 

Background problem

Writing SQL Server stored procedure, if the stored procedure is defined in the temporary table,
some people are used when a stored procedure ends of a temporary table (drop table #tName) process defined explicitly deleted, but some people do not have this habit,
for the masses know the truth, or like to think people will ask, temporary tables, stored procedures defined in the last delete or not to take the initiative, and why?
Or is not the end of the stored procedure to delete the temporary table more standardized?
More than one person asked this question, tell the truth, I did not know before, just think, explicitly delete or not delete anything, temporary tables are automatically released after the current Session Disconnect
the stored procedure is defined in the interim table, after use, in the end delete or not delete? Delete to delete the explicit and not whether the difference?
This paper will issue a superficial analysis of this, if the wrong places, but also pointed out that hope, thank you.

 

Table structure stored procedure temporary table is slow and there will be reused

So in the end you do not need to be explicitly removed explicitly delete or not to delete what is the difference?
This is the middle point of knowledge related to a temporary table cache, first look at what is cached temporary tables.
Cached temporary tables are a new feature since the 2005 SQL SERVER,
need to write data (metadata, temporary table structure information table) to a temporary database system tables when you create a temporary table, just like normal CRUD operations, this process requires a certain resource consumption
(later say what conditions need to be met is), when certain conditions are met
whenever a user request after the completion (of course, this SQL user request contains the temporary table), the metadata will be a temporary table stored in a temporary database (tempdb) of system tables
, although temporary table in the user's perspective, the current Session is created, other things not visible to the Session, Session is disconnected or after the temporary table is deleted (drop), will not be accessible.
But when the new Session call the same temporary table contains the code to create a temporary table, SQL Server internally before reuse created through the implementation of the Session, without having to define a temporary table again.
So we can save some steps to create a table of resources consumed.

 

The above is a theory, a little below the theoretical experimental demonstration of the above to do, first of all look at the phenomenon of temporary table "reuse" between different Session.
First of all here to view sys.dm_os_performance_counters with the system to determine the number of times to create a temporary table, the name of the system table counter is: Temp Tables Creation Rate.

Create the following stored procedure, stored procedures are defined in a temporary table,

Copy the code
create procedure Proc_TestTempTable
as
begin
    
    create table #t20170413
    (
        col_1 varchar(100) ,
        col_2 varchar(100)
    )

    insert into #t20170413 values ('aaa','bbb');

    select * from #t20170413
    --select * from tempdb.sys.tables where name like '#t20170413%'
end
Copy the code

After the stored procedure is created, when the first performance, to observe a phenomenon, the following screenshot

Obviously, Temp Tables sys.dm_os_performance_counters system table Creation Rate counter is incremented by 1, first create a temporary table that is to say the action took place in the course of the implementation of the stored procedure
and then continue with the above code again

同样的代码,这一次sys.dm_os_performance_counters系统表中的Temp Tables Creation Rate计数器没有加1,
为什么明明是存储过程中定义了临时表,上面执行一次,Temp Tables Creation Rate加1,然后再次执行就不加1了?
这个就是临时表重用的现象(严格说是临时表的表结构或者表定义,而不包含数据),
因为第一次执行存储过程的时候创建了临时表,然后再次执行存储过程的时候就重用了第一次的临时表。  

  那怎么证明该存储过程第二次执行的时候重用了第一次创建的临时表?
  对存储过程稍作修改,存储过程中加一句代码,查询临时库中该临时表信息

  然后执行两次如下代码,下面截图是第二次执行的结果(下面会做解释为什么是第二次的执行的结果),
  在临时表被重用的时候查询出来当前临时表的信息,发现临时表创建次数并没有增加,也就是说临时表被重用了

  既然说临时表重用了,那么临时表一定存在于临时库的系统表中,那么如何证明这个存储过程的临时表在临时库中呢?
  上面显示的临时表的Id是-1297292959,那么这里就临时库中查询Id = -1297292959的表信息,发现果然存在这个一张表。
  临时库中的这个表信息除了名字和modify_date不一样,modify_date据观察是临时表被重用的时间,也就是临时表被重用一次就修改一次modify_date
  其他信息完全一致,这就是说明,存储过程第一次执行完成之后,它所创建的临时表被缓存了起来(至于名字不同,后面再解释),
  当再次执行该存储过程的时候可以重用第一次执行存储过程时候创建的临时表的表结构。

 

存储过程中显式删除临时表,到底有没有用处?

对上面的存储过程做如下修改,在存储过程结束之前显式删除定义的临时表

  然后再次执行如下的测试代码,注意截图是第二次执行的结果(下面会做解释为什么是第二次的执行的结果)

  然后继续在临时库的系统表中查询上述Id的系统,发现临时表依旧存在于系统表中,即便是存储过程中显式删除(drop table #t20170413)

  这里说明,即便在存储过程中显式调用了删除临时表的操作,临时表依旧会存在得临时库的系统表中,也就是说临时表依旧会被缓存。
  并不会因为在存储过程中显式删除而真正的删除,临时表对象会缓存在临时库的系统表中。
  之所以Session中查询到的临时表的名字与系统表中查询到的临时表的名字不同,
  原因是临时表从创建到缓存(当前Session断开之后),在内部只是发生了一个对当前Session临时表重命名的过程。
  被缓存的临时表的重用的过程与上面的类似,也是将缓存的换反向重命名。

事实证明:
对于存储过程的临时表,在满足可缓存的前提下(只是表结构,当然不包括临时表的数据),
你删,或者不删,他都会缓存在临时库中,并不因为显式Drop临时表,临时表就会被真正的删除,这是SQL Server专门为此做的优化,你真的不用为删除临时表而操心或者纠结
这里回到一开始的问题,存储过程中有没有必要显式删除临时表就有答案了:对于存储过程的创建的临时表,没必要删除,对于满足可缓存的临时表对象,想删也删不掉!

 

存储过程中定义的临时表,只有满足一定的条件,才会被缓存重用

  上面说了,临时表的重用是要满足一定条件的,如下条件将会导致临时表无法重用

1,创建临时表的时候存在命名约束(这一点非常操蛋,不仅仅是缓存问题,曾经遇到过坑,有机会演示)
2,在临时表创建之后执行DDL操作,比如创建索引等,但是这个DDL不包括drop 临时表和truncate临时表
3,动态SQL方式创建的临时表
4,在不同的范围之内创建的临时表,应该是存储过程调用另外一个存储过程,另外一个存储过程定义的临时表,这一点还没有具体研究
5,存储过程以WITH RECOMPILE重编译的方式运行


  比如在上面的存储过程,在临时表定义之后,创建一个索引,
  此举将会造成临时表无法重用,这种情况下,不管你删或者不删,存储过程执行完成Session断开之后,临时表都不会缓存(在临时库中)
  这一点就不截图演示了,有兴趣的自己测试

 

  解释另外一个问题:
  既然认为无法删除缓存的临时表,正常情况下,缓存的临时表什么情况下会被删除?
  上面说截图都是第二次运行的截图,因为在存储过程重建之后(create或者alter),这个存储过程中定义的临时表都会被清理掉
  只有重建了存储过程,第一次执行之后,缓存的临时表在第二次执行的时候才能被重用
  当然这一点也和容易验证,缓存临时表之后,然后alter 存储过程,
  然后根据缓存临时表的Id去查询临时库中sys .tables的信息,这个缓存的表会在1~2秒之后被删除(个人测试验证过)
  另外显式执行DBCC FREEPROCCACHE,也能删除缓存的临时表。
  其实也不难理解,缓存的对象是跟执行计划缓存绑定的,如果执行计划本身就不存在了,那么缓存的临时表对象也将会被请处理。

 

并发执行的情况下,临时表能否重用?

  并发线程之间当然不会重用同一个临时表,如果不是这样的话,SQL Server也不用混江湖了,并发的每个线程会创建自己的临时表。
  参考如下截图是在并发情况下,tempdb产生的临时表的情况,每个线程调用存储过程产生的临时表后缀都是不一样的。
  并发调用存储过程的时候,每个线程会产生属于自己的临时表,重用临时表是发生在当前线程执行完成之后,其他Session重新调用存储过程时候才能重用已缓存的临时表。
  鉴于本文不是专门说明临时表的,这里就不多说了。

  

 

显式删除临时表与否的性能测试

既然上面说了,如果存储过程中定义的临时表满足临时表被缓存的条件的情况下,存储过程中是否删除临时表,临时表都一样会被缓存
那么,如果真的指定了显式删除临时表操作,与没有显式指定删除临时表,性能上有没有差别呢?
抱着以数据说话的态度,分别在存储过程中不删除与显式删除临时表,用SQLQueryStress做了一系列的性能测试
结果如下

不显式删除临时表 显式删除临时表

测试结果如下, 

  

  测试过程部分截图(不浪费博客园的图片服务器资源了,随便截了两张)

  

  从测试结果看,确实有一些差异,不过这个差别是非常小的,
  第一组测试结果5000次调用产生了0.07秒的差距
  第二组测试结果20000次调用产生了0.35秒的差距,平均到一次差距也就在微妙级,即便是显式调用删除,对性能来说是有一点点影响,不过这个影响也是无伤大雅。
  不过这个内部的原始一定要弄清楚,有没有必要删除,以及原因,这个才是原则性的问题!

    至于临时表数据占用的空间,也不是说显式删除就释放,不删除就不释放,应该是有后台进程来做这个工作的,个人建议不用为这个问题瞎操心。
  写存储过程的时候,多写一点好一点的SQL语句,比纠结这个强多了。

多啰嗦一句:
有些人的观念是根深蒂固的,对于习惯删除临时表的人,觉得这么做“规范”,“专业”,虽然他没有确切的理由说明显式删除临时表的必要性。
但是你要跟他说没必要删除临时表,一定会激怒他,好多程序员都是这样的,你否认他根深蒂固的一个观点的时候,他是很恼火的。
从生物学上说,这个是属于“印随行为”,如宗教般,在自己处于懵懂期的时候,受到一些说法的影响
或许是当初的师傅说的,或者膜拜的对象这么做了,或者听高人说过这么做比较好,然后自己就一直这么做了并且坚信不疑。
当然,包括我自己在某些时候也有此种行为,思维被曾经的某一些经历固化,然后一直束缚自己的认知。
不过对于无伤大雅的问题,就随他去了,没必要说服他,弄不好他反过来觉得你业余,希望小伙伴们明辨,好似乎跑题了……

 

显式删除临时表与否与临时库空间释放问题

  有人担心说,如果不显式删除临时表,是不是临时表占用的空间无法快速释放?
  其实也不用顾虑,还是以数据说话,这里对比两个一样的存储过程,一个不显式删除临时表,一个显示删除临时表,看看临时数据库中用户对象占用page的情况
  不显式删除临时表的存储过程
  做如下对比测试,借助SQLQueryStress,做一个20线程,每个线程500次循环的测试

      

  测试的过程中,在临时数据库中,利用如下SQL,间隔一秒的频率抓取临时库中user objects对象的数据

  

  The above script to the data recorded using the perspective view of FIG Excel functions, the number of user objects presented to the above-described recording scripts can be clearly found not explicitly delete the temporary table, compared to explicitly delete the temporary tables, the number UserObjecs and no significant differences
  also said the number, without explicitly delete temporary tables, temporary table space objects the situation is not timely release did not occur

  

   So no need to worry, do not explicitly delete temporary tables, temporary table space application can not be released in a timely manner.

  

to sum up:   

  This article from a stored procedure temporary tables need to explicitly delete start with a brief introduction to the phenomenon of temporary tables reuse and prerequisites, and whether necessary to explicitly delete the temporary table,
  while tested in the case of a temporary table to meet reusable temporary table explicitly deleted or performance problems, for temporary tables stored procedures defined, regardless of whether whether the cache reuse, not recommended explicitly deleted.

 

Reference links: https://www.mssqltips.com/sqlservertip/4406/sql-server-temporary-table-caching/
     http://sqlblog.com/blogs/paul_white/archive/2012/08/17/temporary-object -caching-explained.aspx

      http://www.davewentzel.com/content/do-you-explicitly-drop-your-temp-tables

Guess you like

Origin www.cnblogs.com/bgh408/p/11640321.html