【发布时间】:2015-06-16 21:40:13
【问题描述】:
每个月我需要导入 1-150 万行存档数据。我首先将其导入临时表(Tasks$),然后运行存储过程以根据需要插入到永久表中。导入临时表只需几秒钟。但是,存储过程需要 2-3 小时才能运行。有没有比我这样做更好的方法,或者这只是我正在尝试做的事情的本质,而且从长远来看没有办法?
如果我在不合并行的情况下运行它(没有 STUFF/SELECT 命令),它会运行得非常快,所以我知道这就是所有延迟的地方。
CREATE TABLE #Temp_DataArchive
(
EmployeeID int,
StartTime Time(0),
Task nvarchar(25),
Duration int,
Details nvarchar(max),
Weekdays nvarchar(max)
)
INSERT INTO #Temp_DataArchive
SELECT EmployeeID, StartTime, Task, Duration,
STUFF((SELECT DISTINCT ', ' + A.Tasks FROM Tasks$ A
WHERE (A.EmployeeID=B.EmployeeID) AND
(A.StartTime=B.StartTime) AND
(A.Task=B.Task) AND
(A.Duration=B.Duration)
FOR XML PATH('')),1,1,'') As Details,
STUFF((SELECT ', ' + A.Weekdays FROM Tasks$ A
WHERE (A.EmployeeID=B.EmployeeID) AND
(A.StartTime=B.StartTime) AND
(A.Task=B.Task) AND
(A.Duration=B.Duration)
FOR XML PATH('')),1,1,'') As Weekdays
FROM Tasks$ B
GROUP BY EmployeeID, StartTime, Task, Duration
为了完整起见,我应该补充一点,在完成之后,我还需要将 Weekdays 转换为单独的位类型列,我使用以下方法执行此操作,但这只需几秒钟即可运行。
INSERT INTO DataArchive
SELECT EmployeeID, StartTime, Task, Duration, Details,
CASE WHEN Weekdays like '%Monday%' THEN 1 ELSE 0 END AS M,
CASE WHEN Weekdays like '%Tuesday%' THEN 1 ELSE 0 END AS Tu,
CASE WHEN Weekdays like '%Wednesday%' THEN 1 ELSE 0 END AS W,
CASE WHEN Weekdays like '%Thursday%' THEN 1 ELSE 0 END AS Th,
CASE WHEN Weekdays like '%Friday%' THEN 1 ELSE 0 END AS F,
CASE WHEN Weekdays like '%Saturday%' THEN 1 ELSE 0 END AS Sa,
CASE WHEN Weekdays like '%Sunday%' THEN 1 ELSE 0 END AS Su
FROM #Temp_DataArchive
drop table #Temp_DataArchive
编辑:解决方案 - 我的原始临时表 (Tasks$) 上缺少索引。添加这些索引后,插入到 #Temp_DataArchive 的时间从 2-3 小时缩短到 2-3 分钟。
【问题讨论】:
-
很难说到底是什么问题,但是你看过执行计划了吗?只需检查以确保您排除了缺失或非最佳索引。
-
DataArchive 上有任何聚集索引吗?
-
Greg 也打败了我 - 但如果您决定需要索引,您可能会发现您需要在填充临时表之前删除它,然后在选择它之前重新添加它。
-
@Greg - 延迟发生在插入名为
#Temp_DataArchive的临时表中的第一个查询中。我实际上是在查询运行之前创建该表,我将修改我的原始帖子以显示它。 -
不,没必要展示create table,我的意思是,继续隔离问题陈述。删除 INSERT 部分,并仅运行 SELECT。还是慢吗?如果是这样,请查看执行计划。
标签: sql-server sql-server-2008 import