在sql server中优化游标查询

时间:2014-02-24 14:01:48

标签: sql-server

我们拥有一个拥有10,000,000条记录的数据库。以下语句用于将每个记录中的一些单词替换为另一个表中的不同单词,但由于记录太多,执行甚至不能在一整天内完成,无论如何它都可以进行优化吗? / p>

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

1 个答案:

答案 0 :(得分: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