【翻译】[SQL]Table 变数不能建立Index 吗 ?

本文探讨了SQL Server中资料表变数与暂存资料表的区别,特别是在索引建立方面的差异。通过实例演示了如何在创建资料表变数时直接定义索引,以提升查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

到底该使用资料表变数还是暂存资料表来存放一些暂时性处理的资料呢 ?

这几天有朋友询问到一个问题,她看书上说「在SQL Server内,使用暂存资料表时可以建立索引来加速查询,但资料表变数不支援这项作法」。于是她询问我说,为什么还是这么大量地使用资料表变数在我的专案内?

这样的说法是比较容易误解,在读的时候可能要注意一下,在上面的描述是指资料表变数,不允许后来再建立Index,但我们可以在建立资料表变数的时候,就指定好相关的索引在资料表变数上,这样就可以让该资料表变数在使用的时候,搭配索引来做相关搜寻。

因此有兴趣的朋友可以试试看这一段语法:

SET NOCOUNT ON
DECLARE @MyData TABLE( Id INT, ItemName NVARCHAR(100)) ;
DECLARE @Ptr INT = 0 ;

WHILE @Ptr < 100000
BEGIN
    INSERT INTO @MyData VALUES ( @Ptr , LEFT( CAST( ABS( CHECKSUM( CAST( NEWID() AS VARCHAR(128) ) )) AS VARCHAR ) + '000000000' , 10 ));
    SET @Ptr += 1 ;
END ;

SET STATISTICS IO,TIME,XML ON
SELECT * FROM @MyData WHERE ItemName BETWEEN '2056' AND '2057'

SET STATISTICS IO,TIME,XML OFF

这段语法执行后,我们可以看到,当去查找资料的时候,是完全采用Table Scan 的方式去找资料
这里写图片描述
如同一开始所谈到的,这个资料表变数我们并不能再去建立索引,但我们依然可以换个做法,我们把上述的语法在建立资料表变数的时候调整一下

SET NOCOUNT ON
DECLARE @MyData TABLE( Id INT Primary Key, ItemName NVARCHAR(100), Index IX NONCLUSTERED(ItemName) ) ;
DECLARE @Ptr INT = 0 ;

WHILE @Ptr < 100000
BEGIN
    INSERT INTO @MyData VALUES ( @Ptr , LEFT( CAST( ABS( CHECKSUM( CAST( NEWID() AS VARCHAR(128) ) )) AS VARCHAR ) + '000000000' , 10 ));
    SET @Ptr += 1 ;
END ;

SET STATISTICS IO,TIME,XML ON
SELECT * FROM @MyData WHERE ItemName BETWEEN '2056' AND '2057'

SET STATISTICS IO,TIME,XML OFF

此时我们看一下结果,会发现已经从资料表扫描,转换为索引搜寻
这里写图片描述
虽然在上述的范例中,看不出来索引搜寻对整体的效能帮助有多大,但在我个人所遇到的一些案例中,特别是这些暂存资料,如有后续又有跟一些实体资料表去关联的时候,那么有没有建立索引,效能上就会有不小的差异了。而资料表变数在使用上算是非常的便利,但可能大家要注意一下,他还是会去使用Tempdb 来存放资料,并不是所谓的In-Memory Table ,这里可不要搞错了。当然还有比较重要的一点,那就是定序的问题了,暂存资料表的定序在一般状况下是使用系统资料库的定序,而不是使用者资料库的定序,而到了SQL Server 2012 之后,因为有contained database ,因此会使暂存资料表在contained database 下是跟使用者资料库相同的定序,所以使用上就要特别注意当定序不同的时候,彼此之间的关联就会造成一些问题或者是要特别做处理。
文章翻译自:James Fu 的技术学习之路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值