如何加速循环 INSERT INTO 语句?

Abe*_*bel 2 performance insert hints sql-server-2008-r2

我目前使用以下语句,对于 10,000 行,大约需要 150 秒。我尝试删除目标表上的索引,但这没有帮助。在没有INSERT INTO50ms 的情况下运行循环。我需要它来更新大约 3 亿行,我真的等不及 52 天 (!) 才能完成。

以下更新查询的底线是我需要遍历每一行,对 a 执行计算VARBINARY并从中提取正确的值(我们需要去掉打包的VARBINARY字段),并将其存储在一个新表中。

FETCH NEXT FROM LocCities INTO @LocCity 
WHILE (@@FETCH_STATUS = 0)
BEGIN
    -- several sets, removed calculations for clarity
    SET @LocationId = Calculation1()
    SET @CityId = Calculation2()

    IF(@LocCity <> 0)
    BEGIN
        -- left out an inner loop here on the VARBINARY based on its length
        INSERT INTO LocationCities (LocationId, CityId)
        VALUES (@LocationId, @CityId)
    END
    FETCH NEXT FROM RespCursor INTO @TuningRow
END
Run Code Online (Sandbox Code Playgroud)

我知道我可以将WITH关键字与table hints 一起使用,但我不确定该使用什么。我希望最终的更新查询在几个小时内运行,并希望有办法做到这一点。我真的等不及将近两个月了;)。

没有类似的东西BULKINSERT我可以使用吗?

Aar*_*and 5

我真的不认为表提示或 BULKINSERT 会在这里帮助你 - 你的方法仍然是一次处理每个 varbinary 值,无论如何这将是你的失败 - 特别是当你放弃基于集合的查询的想法时因为你“认为这不可能”。

这是一种基于集合的方法,没有可怕的循环或游标。这假设模式始终相同(LocationID 是第一个字节,CityID 是接下来的两个字节)。

DECLARE @x TABLE(x VARBINARY(32));

INSERT @x VALUES(0x010734),(0x030735040736),(0x030742050743060712);

;WITH n(n) AS 
(
  SELECT TOP (300) (number*3)+1 
  FROM [master].dbo.spt_values -- your own Numbers table is better
  WHERE [type] = N'P' ORDER BY number
)
-- INSERT dbo.LocationCities(LocationId, CityId)
SELECT 
  x.x,      -- comment this out before insert 
  LocationID = CONVERT(INT, SUBSTRING(x.x, n, 1)),
  CityID     = CONVERT(INT, SUBSTRING(x.x, n+1, 2))
FROM @x AS x INNER JOIN n ON LEN(x) > n.n;
Run Code Online (Sandbox Code Playgroud)

结果:

x                        LocationID    CityID
---------------------    ----------    ------
0x010734                 1             1844
0x030735040736           3             1845
0x030735040736           4             1846
0x030742050743060712     3             1858
0x030742050743060712     5             1859
0x030742050743060712     6             1810
Run Code Online (Sandbox Code Playgroud)

一些文章将帮助您理解数字表以及为什么在 SQL Server 中生成集远远优于您可以导出的最有效的循环。

  • @Abel 有多种原因。您可以控制索引等,使用压缩,不需要过滤器,不依赖于三部分命名来达到主,添加 SCHEMABINDING 以引用视图/函数,不用担心将来对该表的更改(例如它可能会消失),不受该表中行数的限制(因版本而异),您甚至可以将数字表放在 SQL Server 2014 的内存中。可能还有其他几个原因不在我的舌尖上...... (2认同)