临时表与表变量的深入探究(4)
来源:未知 责任编辑:责任编辑 发表时间:2015-09-17 09:42 点击:次
www.2cto.com
在插入性能上,两者基本一致
7)关联操作上,性能的不同表现
--构造数据
dbcc dropcleanbuffers; --从缓冲池中删除所有清除缓冲区
use TestDB
if object_id('tempdb..#temp') is not null drop table #temp
SELECT IDENTITY(INT, 1, 1) as _rowid, a.ppt, a.GoodsId
INTO #temp
FROM GraspFZDRPWrite001.dbo.Goods a --goods表是一个有记录16049的数据表
GO
--用临时表
SELECT * FROM #temp
WHERE _rowid IN (SELECT max(_rowid) FROM #temp GROUP BY Ppt)
--很快
--用表变量
DECLARE @PDTEMP TABLE (_rowid int, ppt CHAR(1), goodsid INT)
INSERT INTO @PDTEMP SELECT * FROM #temp
SELECT * FROM @PDTEMP
WHERE _rowid IN (SELECT max(_rowid) FROM @PDTEMP GROUP BY ppt)
go
--相当慢,记录几乎出不来
www.2cto.com
为啥会出现以上的结果呢,我们跟踪执行计划可以发现,前者执行计划选择的哈希匹配,后者则是相当缓慢的嵌套循环。
分析原因,因为聚合操作会利用表的统计信息来聚合,表变量没有统计信息,系统默认只能选择嵌套循环,而这导致严重的慢查询的主要原因
我们强制查询使用hash join连接(哈希匹配)
DECLARE @PDTEMP TABLE (_rowid int, ppt CHAR(1), goodsid INT)
INSERT INTO @PDTEMP SELECT * FROM #temp
SELECT * FROM @PDTEMP
WHERE _rowid IN (SELECT max(_rowid) FROM @PDTEMP GROUP BY ppt)
option(hash join)
这时速度跟用临时表一样,但不推荐这样使用,因为一旦这样强制使用,SQLSERVER的自动优化则不会起作用
8)把存储过程中返回的数据集插入到临时表 用于保存存储过程中返回的数据集
CREATE TABLE #sp_who3
( www.2cto.com
SPID INT,
Status VARCHAR(32) NULL
)
go
create procedure pWho AS
select 1 as spid, 'Tomas' as status
union all
select 1 as spid, 'Viviy' as status
go
insert #sp_who3 execute pWho
select * from #sp_who3
DECLARE @PDTEMP TABLE (SPID INT, Status VARCHAR(32) NULL)
INSERT @PDTEMP EXEC pWho
SELECT * FROM @PDTEMP
GO
www.2cto.com
两者都可以正常使用,但是有一点必须注意,对于2008以前的版本,表变量是不支持这样操作的
相关新闻>>
最新推荐更多>>>
- 发表评论
-
- 最新评论 更多>>