过程中是否该显示删除临时表
因为上周准备不够充分。关于过程的优化,还有一点想补充一下,上次的PPT中没有加上这一部分,如有异议请指正。
/*这是对临时表定义时的一段话:
Once its creating level gets out of scope (terminates), a temporary table is automatically destroyed.
If a temporary table was created in the outermost level, it is destroyed when the session is terminated.
If it's created within a stored procedure, it is automatically dropped as soon as the stored procedure is finished.
既然能自动删除,那我们显示删除会带来什么影响呢?它是在什么时候被自动删除的呢?
我们知道tempdb在每次启动服务时都会还原为创建时的大小,因此我们应该根据数据库使用一段时间后实际的大小调整它的初始大小,
以避免每次因为服务重启而带来的文件自增长的开销。
下面我们通过例子来演示一下:
*/
USE Northwind;
GO
IF OBJECT_ID(N'dbo.prc_GetCustomers',N'P') IS NOT NULL
DROP PROC dbo.prc_GetCustomers
GO
CREATE PROC dbo.prc_GetCustomers
AS
SET NOCOUNT ON;
SELECT T1.*
INTO #prc_GetCustomers_T--产生笔记录
FROM dbo.Customers T1,
dbo.Customers T2,
dbo.Customers T3;
WAITFOR DELAY '00:00:30';--延迟30秒观察tempdb空间情况
--DROP TABLE #prc_GetCustomers_T;
GO
--执行之前观察tempdb的Temporary Tables目录下的临时对象
--上面的这些临时对象是在你调用的过程中如果有临时表的话,都会自动创建一个对应的对象。具体名称的定义规则就无从而知了。
--其实这些对象里并没有记录,只是一个元数据的定义,我们可以通过以下查询看到记录数为0
select object_name(o.object_id) as objname,p.rows
from sys.partitions p
join sys.objects o
on p.object_id = o.object_id
where o.name=N'#42DCF4FB';
EXEC dbo.prc_GetCustomers
--执行上面的过程,如果你显示的指定了删除临时表的操作,跟踪事件探察器发现在删除临时表时发生了读取操作。
--等待期间,观察tempdb的Temporary Tables目录下的临时对象,
--你会发现会有一个dbo.#prc_GetCustomers_T加一个标识号的临时对象。
--等过程执行结束再观察此对象就已经被删除了。
--那么为什么会有其它的一些对象也被删除了,这是因为你所创建的临时表
--可能会很大。tempdb会优先考虑在不增加磁盘空间的情况下来满足查询的需求,
--因此如果这时有些已经被不使用的对象,就会被删除掉了。
--SQL2000下因为没有Temporary Tables,如果想观察只能通过sp_spaceused
--查看空间使用便可知是否会自动删除。也许我们可以把SQLSERVER对待临时表的作法看成是
--.NET中的垃圾收集器,删除不再需要的东西。同时,尽量保证不占用过多的磁盘空间。
--tempdb很霸道,它只会扩张,不会收缩。因此如果你看到它长的实在是太大了,可以手动的把它收缩一下。
--但是不要收的太小了,因为文件自增长是会有开销的。
--造成过大的原因,可能是因为临时表确实太大。另一种可能是因为并发的调用临时表的操作过多造成的吧!
--tempdb在2005下使用的频率增加了,因此它对性能的影响也是至关重要的。