【发布时间】:2015-03-04 05:46:59
【问题描述】:
我有以下存储过程,它在表中删除和插入行。它运行缓慢。
我已经阅读了各种提案并已实施:
- 批量删除行并使用派生表
- 禁用 FK
- where 子句中的字段的索引。
所以它应该走的路是:
表有大约 1000 万条记录。
每天我需要刷新大约 15-30% 的内容。我用这个SP来做。
来源:
CREATE PROCEDURE [dbo].[spIncrementalUpdate]
-- Add the parameters for the stored procedure here
@table_inc nvarchar(30),
@table_target nvarchar(30),
@table_date nvarchar(30),
@field1 nvarchar(10),
@field2 nvarchar(10)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @logmessage as nvarchar(2048)
DECLARE @logdatacode as int
DECLARE @cmd as nvarchar(max)
DECLARE @fromjulian nvarchar(10)
DECLARE @datadate datetime
DECLARE @datadate_str nvarchar(10)
DECLARE @rows int
DECLARE @ParmDefinition nvarchar(500)
select @fromjulian = '114000'
print 'Using ' + @fromjulian
--
-- GET THE ROW COUNT OF THE INC TABLE.
--
IF @field2 = ''
BEGIN
SET @cmd = N'SELECT @retval = count(*) from ' +
@table_inc + ' where ' + @field1 +' > ' + @fromjulian
END
ELSE
BEGIN
SET @cmd = N'SELECT @retval = count(*) from ' +
@table_inc + ' where ' + @field1 +' > ' + @fromjulian +
' OR ' + @field2 +' > ' + @fromjulian
END
SET @ParmDefinition = N'@retval int OUTPUT'
EXEC sp_executesql @cmd, @ParmDefinition, @retval = @rows OUTPUT
--
if @rows <> 0
BEGIN
SET @logmessage = @table_inc + ' has ' +
cast(@rows as nvarchar(10)) +
' rows after ' + @fromjulian + ', deleting'
SET @logdatacode = 1000
--
-- Delete the records from original table based on @fromjulian
--
IF @field2 = ''
BEGIN
SET @cmd = N'delete ' + @table_target +
' from (select top(50000) * from ' + @table_target +
' where ' + @field1 + ' > ' + @fromjulian +
' order by ' + @field1 + ') ' +
@table_target
print @cmd
END
ELSE
BEGIN
SET @cmd = N'delete ' + @table_target +
' from (select top(50000) * from ' +
@table_target +
' where ' + @field1 + ' > ' + @fromjulian +
' OR ' + @field2 +' > ' + @fromjulian +
' order by ' + @field1 + ',' + @field2 + ') ' +
@table_target
print @cmd
END
SELECT 1
WHILE @@ROWCOUNT <> 0
BEGIN
EXEC sp_executesql @cmd
END
--
-- Inserting the records to target from INC table
--
IF @field2 = ''
BEGIN
SET @cmd = N'insert into ' + @table_target +
' select * from ' + @table_inc +
' where ' + @field1 +' > ' + cast(@fromjulian as nvarchar(10))
print @cmd
END
ELSE
BEGIN
SET @cmd = N'insert into ' + @table_target +
' select * from ' + @table_inc +
' where ' + @field1 +' > ' + cast(@fromjulian as nvarchar(10)) +
' OR ' + @field2 +' > ' + cast(@fromjulian as nvarchar(10))
print @cmd
END
print @cmd
EXEC sp_executesql @cmd
END
ELSE
BEGIN
SET @logmessage = 'NO ROWS IN ' + @table_inc + ' AFTER ' + cast(@fromjulian as nvarchar(10))
SET @logdatacode = 1001
END
--
-- LOG
--
INSERT INTO YLA_GROUP.[dbo].[sysssislog]
([event]
,[computer]
,[operator]
,[source]
,[sourceid]
,[executionid]
,[starttime]
,[endtime]
,[datacode]
,[databytes]
,[message])
VALUES
('spIncrementalUpdate','','','',NEWID(),NEWID(),getdate(),getdate(),@logdatacode,null,@logmessage)
print cast(@logdatacode as nvarchar(10)) + ' - ' + @logmessage
END
【问题讨论】:
标签: sql-server performance tsql optimization delete-row