2014-02-24 107 views
-1

我們擁有一個擁有更多10,000,000條記錄的數據庫。以下語句用於用每個記錄中的某些詞替換另一個表中的另一個詞,但由於有很多記錄執行甚至在一整天內都沒有完成,因此它是否可以優化?在sql server中優化遊標查詢

DECLARE My_Cursor CURSOR 
FOR 
    SELECT 
     full_santance 
    , id 
    FROM 
     dbo.combined 
    WHERE 
     id BETWEEN 9000000 AND 10000000 

DECLARE My_Cursor_r CURSOR 
FOR 
    SELECT 
     old 
    , new 
    FROM 
     dbo.changesTable 

DECLARE @full_santance varchar(500) 
DECLARE @id numeric(18, 0) 
DECLARE @word_old varchar(500) 
DECLARE @word_new varchar(500) 
DECLARE @corrected varchar(500) 
DECLARE @r_word varchar(500) 

OPEN My_Cursor 
FETCH NEXT FROM My_Cursor INTO @full_santance, @id 
WHILE @@FETCH_STATUS = 0 
     BEGIN 
      SET @corrected = @full_santance 

      OPEN My_Cursor_r 
      FETCH NEXT FROM My_Cursor_r INTO @word_old, @word_new 
      WHILE @@FETCH_STATUS = 0 
        BEGIN 
         IF @corrected LIKE '%[^a-z]' + REPLACE(RTRIM(@word_old),'_', '') + '[^a-z]%' 
          OR @corrected LIKE '%[^a-z]' + REPLACE(RTRIM(@word_old), '_', '') 
          OR @corrected LIKE REPLACE(RTRIM(@word_old), '_','') + '[^a-z]%' 
          OR @corrected LIKE REPLACE(RTRIM(@word_old), '_','') 
          BEGIN 
           SET @corrected = REPLACE(@corrected,REPLACE(RTRIM(@word_old),'_', ' '),REPLACE(RTRIM(@word_new),'_', ' ')) 
          END 

         FETCH NEXT FROM My_Cursor_r INTO @word_old, @word_new 
        END 

      CLOSE My_Cursor_r 

      IF @corrected <> @full_santance 
       BEGIN 
        UPDATE 
         dbo.combined 
        SET 
         full_santance = @corrected 
        WHERE 
         id = @id 
       END 

      FETCH NEXT FROM My_Cursor INTO @word, @id 
     END 
CLOSE My_Cursor 
DEALLOCATE My_Cursor 
DEALLOCATE My_Cursor_r 
+0

同時顯示錶和表列的小樣本數據需要由其中一個和兩個表的關係進行更新。 – KumarHarsh

+0

我的猜測是內層遊標可能很容易重寫而沒有遊標。另外 - 這是一個定期運行或是一次性更新?因爲如果它是一次性的,我會正確地嘗試在另一個表/數據庫中執行此操作,然後一次更新所有行。 (10.000.000條記錄可能聽起來很多,但它不應該是)。如果它經常運行,那爲什麼? –

回答

1
DECLARE @combined TABLE (id int, full_santance varchar(max)) 
INSERT @combined VALUES 
(1, 'the quick brown fox jumped over the lazy dog'), 
(2, 'the dog days of summer') 

DECLARE @changesTable TABLE (old varchar(max), new varchar(max)) 
INSERT @changesTable VALUES 
('dog','cat'), 
('the','a') 

SELECT 
    id, 
    LTRIM((
    SELECT ' '+ISNULL(new,word) 
    FROM @combined c2 
    CROSS APPLY (SELECT CAST('<a>'+REPLACE(full_santance,' ','</a><a>')+'</a>' AS xml) xml1) t1 
    CROSS APPLY (SELECT n.value('.','varchar(max)') AS word FROM xml1.nodes('a') x(n)) t2 
    LEFT JOIN @changesTable ON word = old 
    WHERE c1.id = c2.id 
    FOR XML PATH('') 
)) 
FROM @combined c1 
+0

這正是我所需要的,非常感謝 – user1097275