SQL 性能缓慢(改进 Insert Into Temp Table)
SQL Performance Slow (Improve Insert Into Temp Table)
我一直在研究一个旧的审计存储过程,它 运行 很慢,我在应用索引和使查询更可搜索方面取得了一些成功。
但是存储过程仍然需要一分钟才能完成。我认为问题在于 temp table 插入。我确实尝试将索引应用于临时 table 但这只会降低性能,因为:
The number of indexes on a table is the most dominant factor for
insert performance. The more indexes a table has, the slower the
execution becomes. The insert statement is the only operation that
cannot directly benefit from indexing because it has no where clause.
SQL代码
我已经在下面发布了处理时间最长的审计过程的代码片段,并包含了执行计划。
SELECT dbo.[Audit Result Entry Detail].PK_ID,
dbo.[Audit Result Entry Detail].......
45-50 other columns selected from Audit Result Entry Detail
(Note i need to select all these)
dbo.[Audit Register].Audit_Date,
dbo.[Audit Register].Audit_Type,
dbo.[Audit Register].ContextUser
INTO #temp5
FROM dbo.[Audit Result Entry Detail]
INNER
JOIN dbo.[Audit Register]
ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID
INNER
JOIN (
SELECT MAX(Audit_Date) AS DATE,
FK_RegisterID
FROM dbo.[Audit Result Entry Detail]
INNER
JOIN dbo.[Audit Register]
ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID
WHERE Audit_Date >= @StartDate AND Audit_Date < DATEADD(dd,1,@EndDate)
--WHERE ((SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) >= @StartDate
-- AND (SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) <= @EndDate)
AND part_number = @ParticipantNumber
GROUP
BY FK_RegisterID
) dt
ON dbo.[Audit Result Entry Detail].FK_RegisterID = dt.FK_RegisterID
AND dbo.[Audit Register].Audit_Date = dt.[date]
WHERE part_number = @ParticipantNumber
执行计划:
我认为瓶颈是#temp5 table,我的问题是有什么方法可以加快插入临时文件的速度table 或者是否有更好的替代临时文件 table?
我想这个问题可能有几个不同的原因。
至少,假设是由于一条记录中的大量字段会导致临时堆中的页面溢出 table。除此之外,tempdb 中可能存在争用,甚至速度很慢。所以,一般的建议可能是:
1. 如前所述,尽量不要使用 temp table。
2. 如果可能,尽量限制记录大小以适合一页。或者更好,如果您可以将 2-3 条记录放入一页。
3. 如果可能的话,使用 "staging" table 和聚簇索引,而不是 temp table。不要截断 table,只做删除。
4. 如果使用 temp table:在插入之前创建 table,上面有聚簇索引。
5. Fallow Paul Randal 关于 TempDB 的建议:http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-27-of-30-troubleshooting-tempdb-contention/
为了更深入的故障排除,我建议在执行该查询期间捕获等待、锁定、I/O、内存和 CPU activity。
我一直在研究一个旧的审计存储过程,它 运行 很慢,我在应用索引和使查询更可搜索方面取得了一些成功。
但是存储过程仍然需要一分钟才能完成。我认为问题在于 temp table 插入。我确实尝试将索引应用于临时 table 但这只会降低性能,因为:
The number of indexes on a table is the most dominant factor for insert performance. The more indexes a table has, the slower the execution becomes. The insert statement is the only operation that cannot directly benefit from indexing because it has no where clause.
SQL代码
我已经在下面发布了处理时间最长的审计过程的代码片段,并包含了执行计划。
SELECT dbo.[Audit Result Entry Detail].PK_ID,
dbo.[Audit Result Entry Detail].......
45-50 other columns selected from Audit Result Entry Detail
(Note i need to select all these)
dbo.[Audit Register].Audit_Date,
dbo.[Audit Register].Audit_Type,
dbo.[Audit Register].ContextUser
INTO #temp5
FROM dbo.[Audit Result Entry Detail]
INNER
JOIN dbo.[Audit Register]
ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID
INNER
JOIN (
SELECT MAX(Audit_Date) AS DATE,
FK_RegisterID
FROM dbo.[Audit Result Entry Detail]
INNER
JOIN dbo.[Audit Register]
ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID
WHERE Audit_Date >= @StartDate AND Audit_Date < DATEADD(dd,1,@EndDate)
--WHERE ((SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) >= @StartDate
-- AND (SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) <= @EndDate)
AND part_number = @ParticipantNumber
GROUP
BY FK_RegisterID
) dt
ON dbo.[Audit Result Entry Detail].FK_RegisterID = dt.FK_RegisterID
AND dbo.[Audit Register].Audit_Date = dt.[date]
WHERE part_number = @ParticipantNumber
执行计划:
我认为瓶颈是#temp5 table,我的问题是有什么方法可以加快插入临时文件的速度table 或者是否有更好的替代临时文件 table?
我想这个问题可能有几个不同的原因。
至少,假设是由于一条记录中的大量字段会导致临时堆中的页面溢出 table。除此之外,tempdb 中可能存在争用,甚至速度很慢。所以,一般的建议可能是:
1. 如前所述,尽量不要使用 temp table。
2. 如果可能,尽量限制记录大小以适合一页。或者更好,如果您可以将 2-3 条记录放入一页。
3. 如果可能的话,使用 "staging" table 和聚簇索引,而不是 temp table。不要截断 table,只做删除。
4. 如果使用 temp table:在插入之前创建 table,上面有聚簇索引。
5. Fallow Paul Randal 关于 TempDB 的建议:http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-27-of-30-troubleshooting-tempdb-contention/
为了更深入的故障排除,我建议在执行该查询期间捕获等待、锁定、I/O、内存和 CPU activity。