SQL Server

SQL Server Error 601: Could not continue scan with NOLOCK due to data movement

Na produkčním serveru se pravidelně při větší update dat začalo objevovat následující chybové hlášení: ‘Error 601: Could not continue scan with NOLOCK due to data movement’. Produkční server běží na SQL Server 2008R2 SP1 Standard edition. Po delší hledání se podařilo najít popis chyby v tomto KB:  http://support.microsoft.com/kb/960770/en-us.

V našem konkrétním příkladě se chyba objevovala v kódu, který využíval následující logiku:

DECLARE @TempTable TABLE (...)

INSERT INTO @TempTable
    SELECT * FROM ....

INSERT INTO @TempTable
    select *
    from ( select distinct * from @TempTable ) tt
        cross join dbo.TableA a
    where 
        a.Col1 >=  1

Problematickou operací je zde vkládání do @TempTable ve stejném okamžiku, kdy se z tabulky čte. Zápis do tabulky způsobí realokaci stránek, které mají být teprve přečteny a v okamžiku čtení se již nenacházejí na svém místě.

Řešením je intuitivní přepsání kódu tak, že data se nejprve vloží do dočasné tabulky #Distinct a tato tabulka je následně využita k získání dat pro vložení do @TempTable. Tím se předejde realokaci stránek a výše zmíněné chybě.

DECLARE @TempTable TABLE (...)

INSERT INTO @TempTable
    SELECT * FROM ....

SELECT DISTINCT * 
    INTO #Distinct
FROM @TempTable

INSERT INTO @TempTable
    SELECT *
    FROM #Distinct tt
        cross join dbo.TableA a
    WHERE 
        a.Col1 >=  1

Leave a Reply

Your email address will not be published. Required fields are marked *