2017-08-12 74 views
1

我在優化SQL查詢以執行一些數據清理方面存在問題。SQL Server更新語句的性能

事實上,我有一個表格,它是一個多重特殊字符和單詞的引用。讓我們把它ABNORMAL(ID,PATTERN)

我也有另一個表含,我想從它消除存在於表ABNORMAL所有字符來清洗柱(NAMEINDIVIDUALS

目前,我試圖使用更新語句,但我不知道是否有更好的方法來做到這一點。

方法的一個

使用while循環來構建一個空白'一個替換包含所有字符從ABNORMALS和使用做一個更新內置REPLACE

DECLARE @REPLACE_EXPRESSION nvarchar(max) ='REPLACE(NAME,'''','''')' 
DECLARE @i int = 1 
DECLARE @nbr int = (SELECT COUNT(*) FROM ABNORMAL) 
-- CURRENT_CHARAC 
DECLARE @CURRENT_CHARAC nvarchar(max) 
-- NEW REPLACE EXPRESSION TO IMBRICATE INTO THE REPLACE EXPRESSION VARIABLE 
DECLARE @CURR_REP NVARCHAR(max) 
-- STRING TO BUILD AN SQL QUERY CONTAINING THE REPLACE EXPRESSION 
DECLARE @UPDATE_QUERY nvarchar(max) 
WHILE @i < @nbr 
BEGIN 
    SELECT @CURRENT_CHARAC=PATTERN FROM CLEANSING_STG_PRISM_FRA_REF_UNSIGNIFICANT_VALUES WHERE [email protected] ; 
    SET @REPLACE_EXPRESSION = REPLACE(@REPLACE_EXPRESSION ,'NAME','REPLACE(NAME,'+''''[email protected]_CHARAC+''''+','''')') 
    set @[email protected]+1 
END 
SET @UPDATE_QUERY = 'UPDATE INDIVIDUAL SET NAME ='+ @REPLACE_EXPRESSION 
EXEC sp_executesql @UPDATE_QUERY 

方法有兩個

使用while循環選擇異常中的每個字符並使用包含要刪除字符的替換進行更新:

DECLARE @i int = 1 
DECLARE @nbr int = (SELECT COUNT(*) FROM ABNORMAL) 
-- CURRENT_CHARAC 
DECLARE @CURRENT_CHARAC nvarchar(max) 
-- STRING TO BUILD AN SQL QUERY CONTAINING THE REPLACE EXPRESSION 
DECLARE @UPDATE_QUERY nvarchar(max) 
WHILE @i < @nbr 
BEGIN 
    SELECT @CURRENT_CHARAC=PATTERN FROM CLEANSING_STG_PRISM_FRA_REF_UNSIGNIFICANT_VALUES WHERE [email protected] ; 
    UPDATE INDIVIDUAL 
    SET NAME = REPLACE(NAME,@CURRENT_CHARAC,'') 
    SET @[email protected]+1 
END 

我已經測試了兩百萬條記錄的兩種方法,並且我發現第一種方法比第二種方法更快。我會知道你是否已經做了一些類似和新的(更好的)想法來嘗試。

回答

0

如果您正在使用SQL Server 2017你可以使用TRANSLATE,避免動態SQL:

SELECT i.* 
    , REPLACE(TRANSLATE(i.NAME, f, REPLICATE('!', s.l)), '!', '') AS cleansed 
FROM INDIVIDUALS i 
OUTER APPLY (SELECT STRING_AGG(PATTERN, '') AS f 
        ,LEN(STRING_AGG(PATTERN,'')) AS l 
      FROM ABNORMAL) AS s 

DBFiddle Demo


反正第一次的做法是更好的becasue你做一個UPDATE,用第二種方法你在一次刪除字符一個字符(所以你將有多個UPDATE)。

我也會用兩種方法跟蹤事務日誌的增長。

+0

你好,感謝您的反饋。不幸的是,我使用的是SQL Server 2016.但是,請您澄清一下「跟蹤事務日誌」是什麼意思?以及如何優化我的查詢? –

0

如果沒有太多字符需要清理,那麼這個技巧可能會奏效。

基本上,您將生成1個大的更新語句,並將表中的每個值替換爲要刪除的字符。

示例代碼:

測試數據(使用臨時表)

create table #ABNORMAL_CHARACTERS (id int identity(1,1), chr varchar(30)); 
insert into #ABNORMAL_CHARACTERS (chr) values ('!'),('&'),('#'); 

create table #INDIVIDUAL (id int identity(1,1), name varchar(30)); 
insert into #INDIVIDUAL (name) values ('test 1 &'),('test !&#2'),('test 3'); 

代碼:

declare @FieldName varchar(30) = 'name'; 
declare @Replaces varchar(max) = @FieldName; 
declare @UpdateSQL varchar(max); 

select @Replaces = concat('replace('[email protected]+', ', ''''+chr+''','''')') from #ABNORMAL_CHARACTERS order by id; 

set @UpdateSQL = 'update #INDIVIDUAL 
set name = '[email protected] + ' 
where exists (select 1 from #ABNORMAL_CHARACTERS where charindex(chr,name)>0)'; 

exec (@UpdateSQL); 

select * from #INDIVIDUAL; 

測試here on rextester

如果你有一個可以做正則表達式替換的UDF。 例如here
然後@Replaces變量可以簡化爲只有1個RegexReplace函數和一個模式。