SQL Server,带有截断的临时表与带有删除的表变量

发布于 2024-08-29 08:55:02 字数 174 浏览 7 评论 0原文

我有一个存储过程,在其中创建一个通常包含 1 到 10 行的临时表。该表在存储过程期间被截断和填充多次。它被截断,因为这比删除更快。 当我因使用删除而受到惩罚(截断不适用于表变量)时,通过用表变量替换此临时表是否会提高性能

虽然表变量主要在内存中并且通常比临时表更快,但我是否会丢失任何数据通过删除而不是截断来受益?

I have a stored procedure inside which I create a temporary table that typically contains between 1 and 10 rows. This table is truncated and filled many times during the stored procedure. It is truncated as this is faster than delete.
Do I get any performance increase by replacing this temporary table with a table variable when I suffer a penalty for using delete (truncate does not work on table variables)

Whilst table variables are mainly in memory and are generally faster than temp tables do I loose any benefit by having to delete rather than truncate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南城追梦 2024-09-05 08:55:02

运行以下脚本,似乎表变量

CREATE TABLE #Temp(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO #Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    TRUNCATE TABLE #Temp
END

DROP TABLE #TEMP

GO

DECLARE @Temp TABLE(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO @Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    DELETE FROM @Temp
END

来自 Sql Profiler 的更好选项

CPU     Reads   Writes  Duration
36375     2799937   0       39319

vs

CPU     Reads   Writes  Duration
14750   1700031 2       17376   

Running the followign to scripts, it would seem that the Table Variable is the better option

CREATE TABLE #Temp(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO #Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    TRUNCATE TABLE #Temp
END

DROP TABLE #TEMP

GO

DECLARE @Temp TABLE(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO @Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    DELETE FROM @Temp
END

From Sql Profiler

CPU     Reads   Writes  Duration
36375     2799937   0       39319

vs

CPU     Reads   Writes  Duration
14750   1700031 2       17376   
濫情▎り 2024-09-05 08:55:02

坦率地说,只有 10 或 20(甚至 100)个条目,速度上的任何差异都将在亚纳秒范围内。算了——别在这上面浪费一秒钟的时间——这不是问题!

一般来说,

  • 表变量将在内存中保留一定大小 - 如果超出该大小,它们也会被交换到 tempdb 数据库中的磁盘 - 就像临时表一样。另外:如果临时表只有少数条目,那么它们很可能存储在单个 8k 页面上,并且一旦您访问其中一个条目,整个页面(以及整个临时表)就会位于 SQL Server 内存中 - 所以即使在这里,表变量实际上也没有太多好处...

  • 表变量不支持索引或统计信息,这意味着如果您有多个条目,并且特别是如果您需要搜索和查询这个“实体”,您最好使用临时表

所以总而言之:我个人使用临时表比表变量更频繁,特别是如果我有超过 10 个条目或类似的东西。在性能方面,与表变量可能具有的任何潜在收益相比,能够对临时表进行索引并对其进行统计通常会带来很大的回报。

Quite frankly, with only 10 or 20 (or even 100) entries, any difference in speed would be in a sub-nanosecond realm. Forget about it - don't even waste a second of your brain time on this - it's a non-issue!

In general

  • table variables will be kept in memory up a certain size - if they go beyond that, they're swapped out to disk in the tempdb database, too - just like temporary tables. Plus: if a temporary table has only a handful of entries, they'll most like be stored on a single 8k page anyway, and as soon as you access one of the entries, that entire page (and thus the whole temporary table) will be in SQL Server memory - so even here, there's really not a whole lot of benefits to table variables...

  • table variables don't support indices nor statistics, which means if you have more than a handful of entries, and especially if you need to search and query this "entity", you're better off with a temporary table

So all in all : I personally use temporary tables more often than table variables, especially if I have more than 10 entries or something like that. Being able to index the temp table, and having statistics on it, usually pays off big time compared to any potential gain a table variable might have, performance-wise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文