以下查询导致SQL Server 2014 TEMPDB.MDF增长到40Gb并运行大约一个小时。
对于非NVARCHAR(MAX)
的列的类似查询需要几分钟。
正在更新的表格大约有700万行。
将AND C.SQLStmt IS NOT NULL
添加到最后改进了这一点。
任何帮助都将不胜感激。
UPDATE R
SET R.SQLStmt = C.SQLStmt
FROM SampleResults R
JOIN SampleTests T ON T.SampleCode = R.SampleCode
AND T.TestPosition = R.TestPosition
JOIN TestComponents C ON T.TestCode = C.TestCode
AND T.TestVersion = C.AuditNumber
AND R.ComponentColumn = C.ComponentColumn
AND R.ComponentRow = C.ComponentRow
WHERE T.AuditFlag = 0
AND R.AuditFlag = 0
AND C.SQLStmt IS NOT NULL
这是this question的后续内容,我没有足够的声誉可以评论。
执行计划是:
Update
Cost: 0%
|
Cluseterd Index Updated
[SampleResults].[pk_SampleResults]
Cost: 27%
|
Top
COST: 0%
|
Sort
(Distinct Sort)
Cost: 31%
|
Nested Loops Index Seek (NonClustered)
(Inner Join) - [SampleTests].[SampleTestsAuditFlag...
Cost: 0% Cost: 10%
|
Nested Loops Key Lookup (Clustered)
(Inner Join) - [SampleResults].[pk_SampleResults]...
Cost: 0% Cost: 15%
|
Nested Loops Index Seek (NonClustered)
(Inner Join) - [SampleResults].[SampleResultsCompo...
Cost: 0% Cost: 9%
|
Filter
Cost: 0%
|
Clustered Index Scan (Clustered)
[TestComponents].[pk_TestComponents...
Cost: 9%
答案 0 :(得分:0)
由于列中存储的实际数据的最大大小仅为392个字符,因此最终的解决方案是:
1)暂时将源列和目标列(SampleResults.SQLStmt和TestComponents.SQLStmt)的大小更改为392个字符。 2)做更新。 3)将源列和目标列的大小更改为新的更合理的4000个字符大小。
DECLARE @tempSQLStmtLength SMALLINT = (SELECT MAX(LEN(SQlStmt)) FROM TestComponents WHERE SQlStmt IS NOT NULL)
IF @tempSQLStmtLength IS NOT NULL AND @tempSQLStmtLength > 0
BEGIN
-- Temporarily reduce size of SQLStmt columns so that update is as quick as possible.
EXEC('ALTER TABLE SampleResults ALTER COLUMN SQLStmt NVARCHAR(' + @tempSQLStmtLength +') NULL')
EXEC('ALTER TABLE TestComponents ALTER COLUMN SQLStmt NVARCHAR(' + @tempSQLStmtLength + ') NULL')
-- Perform update.
UPDATE R SET R.SQLStmt = C.SQLStmt FROM SampleResults R JOIN SampleTests T ON T.SampleCode = R.SampleCode AND T.TestPosition = R.TestPosition JOIN TestComponents C ON (T.TestCode = C.TestCode OR T.TestCode + '-' + CAST(T.TestPosition AS VARCHAR(5)) + '-' + T.SampleCode = C.TestCode) AND T.TestVersion = C.AuditNumber AND R.ComponentColumn = C.ComponentColumn AND R.ComponentRow = C.ComponentRow WHERE T.AuditFlag = 0 AND R.AuditFlag = 0 AND C.SQLStmt IS NOT NULL
-- Now that update is finished, set SQLStmt columns to their final new size.
ALTER TABLE SampleResults ALTER COLUMN SQLStmt NVARCHAR(4000) NULL
ALTER TABLE TestComponents ALTER COLUMN SQLStmt NVARCHAR(4000) NULL
END;
TEMPDB.MDB仅增长到2.8Gb并花了几分钟。