Sql server 在ms sql中在时间表中输入行的更快方法

Sql server 在ms sql中在时间表中输入行的更快方法,sql-server,performance,Sql Server,Performance,我需要填写一个时间表,以便将其用于加入reporting services中的数据。 通常,我使用以下代码执行此操作: TRUNCATE TABLE tqTimeTable DECLARE @CNT int DECLARE @DATE datetime DECLARE @END int SET @CNT = 1 SET @DATE = 25567 -- 01.01.1970 SET @END = 20000 -- + 20k days => years 2024 WHILE(@C

我需要填写一个时间表,以便将其用于加入reporting services中的数据。 通常,我使用以下代码执行此操作:

TRUNCATE TABLE tqTimeTable

DECLARE @CNT int
DECLARE @DATE datetime
DECLARE @END int

SET @CNT  = 1
SET @DATE = 25567 -- 01.01.1970
SET @END  = 20000 -- + 20k days => years 2024

WHILE(@CNT < @END)
BEGIN
  INSERT INTO tqTimeTable (Tag, Monat, Jahr)
  VALUES (DATEADD(day,@CNT,@DATE), MONTH(DATEADD(day,@CNT,@DATE)), YEAR(DATEADD(day,@CNT,@DATE)))
  SET @CNT = @CNT + 1
END;
但这在我的测试系统上需要2分钟左右的时间,所以我希望有人也有同样的问题,并且比我解决得更好。 当我从.NET连接触发此语句时,我需要一个更快的解决方案,或者如果没有解决方案,则需要提高连接超时时间。

只需添加

BEGIN TRAN
WHILE(@CNT < @END)
BEGIN
  INSERT INTO tqTimeTable (Tag, Monat, Jahr)
  VALUES (DATEADD(day,@CNT,@DATE), MONTH(DATEADD(day,@CNT,@DATE)), YEAR(DATEADD(day,@CNT,@DATE)))
  SET @CNT = @CNT + 1
END;
COMMIT
将加快它的速度,因为您正在执行许多单独的提交,这些提交都需要将日志写入光盘。不过,我会在一条语句中执行基于集合的插入

   WITH E1(N) AS 
    (
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
    )                                       -- 1*10^1 or 10 rows
    , E2(N) AS (SELECT 1 FROM E1 a, E1 b)   -- 1*10^2 or 100 rows
    , E4(N) AS (SELECT 1 FROM E2 a, E2 b)   -- 1*10^4 or 10,000 rows
    , E8(N) AS (SELECT 1 FROM E4 a, E4 b)   -- 1*10^8 or 100,000,000 rows
    , NUMS(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM  E8)
INSERT INTO tqTimeTable
            (Tag,
             Monat,
             Jahr)
SELECT DATEADD(day, N, @DATE),
       MONTH(DATEADD(day, N, @DATE)),
       YEAR(DATEADD(day, N, @DATE))
FROM   NUMS
WHERE  N <= 20000 
简单地添加

BEGIN TRAN
WHILE(@CNT < @END)
BEGIN
  INSERT INTO tqTimeTable (Tag, Monat, Jahr)
  VALUES (DATEADD(day,@CNT,@DATE), MONTH(DATEADD(day,@CNT,@DATE)), YEAR(DATEADD(day,@CNT,@DATE)))
  SET @CNT = @CNT + 1
END;
COMMIT
将加快它的速度,因为您正在执行许多单独的提交,这些提交都需要将日志写入光盘。不过,我会在一条语句中执行基于集合的插入

   WITH E1(N) AS 
    (
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
    )                                       -- 1*10^1 or 10 rows
    , E2(N) AS (SELECT 1 FROM E1 a, E1 b)   -- 1*10^2 or 100 rows
    , E4(N) AS (SELECT 1 FROM E2 a, E2 b)   -- 1*10^4 or 10,000 rows
    , E8(N) AS (SELECT 1 FROM E4 a, E4 b)   -- 1*10^8 or 100,000,000 rows
    , NUMS(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM  E8)
INSERT INTO tqTimeTable
            (Tag,
             Monat,
             Jahr)
SELECT DATEADD(day, N, @DATE),
       MONTH(DATEADD(day, N, @DATE)),
       YEAR(DATEADD(day, N, @DATE))
FROM   NUMS
WHERE  N <= 20000 

奇怪的在我的系统上,这大约需要5秒钟。在SQLFiddle上大约13秒:奇怪。在我的系统上,这大约需要5秒钟。在SQLFiddle上大约13秒:事务就是它,现在只需1秒钟就可以工作了…你的基于集合的语句在这里弹出一个错误,语法错误,但时间已经快到可以接受的程度了,所以不再需要解决这个问题…@YvesR-如果前面有任何其他语句,它们需要用分号终止。是的,它现在可以正确地工作;速度。但老实说,这个查询对我来说是非常科学的:我根本不明白它是如何工作的。事务是它,现在工作在1秒之内…你的基于集合的语句在这里弹出一个错误,语法接近错误,但时间现在快得可以接受了,所以不再需要解决这个问题了…@YvesR-如果前面有任何其他语句,它们需要以分号结尾;速度。但老实说,这个问题对我来说太像火箭科学了:我根本不明白它是如何工作的。