테이블에 행을 삭제하고 삽입하는 다음 저장 프로 시저가 있습니다. 천천히 달리고 있어요.SQL Server에서 증분 배치 삭제 및 삽입 작업이 매우 느립니다.
나는 다양한 제안을 읽고 난 구현 :
- 가 일괄 행을 삭제하고 where 절에있는 필드에 테이블을
- 안 FK
- 인덱스 파생 사용.
는 그래서 가야 방법은 다음과 같습니다
테이블은 약 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
나는 물건을 빠르게하기 위해 파생 된 테이블에서 주문을 사용한 어딘가 (지금은 링크를 찾을 수 없음)를 보았습니다. 주문하는 필드에 인덱스가 설정되어 있다는 것을 유의하십시오. – e4rthdog
@ e4rthdog 순간에 ORDER BY가 성능을 어떻게 향상시킬 수 있는지 알 수 없습니다. 내 생각에, 그것에 대해 생각해 봅시다, 당신은 커버 인덱스가 있더라도 그것을 만드는 또 다른 작업입니다. ORDER BY없이 시도해 볼 가치가 있다고 생각합니다. – dario
이것은 내가 말하고자하는 것입니다 : http://sqlblogcasts.com/blogs/simons/archive/2009/05/22/DELETE-TOP-x-rows-avoiding-a-table-scan.aspx – e4rthdog