Pregunta

Las siguientes consultas toman 70 minutos y 1 minuto respectivamente en una máquina estándar para 1 millón de registros. ¿Cuáles podrían ser las posibles razones?

Consulta [01:10:00]

SELECT * 
FROM cdc.fn_cdc_get_net_changes_dbo_PartitionTest(
    CASE WHEN sys.fn_cdc_increment_lsn(0x00)<sys.fn_cdc_get_min_lsn('dbo_PartitionTest')        
        THEN sys.fn_cdc_get_min_lsn('dbo_PartitionTest')        
        ELSE sys.fn_cdc_increment_lsn(0x00) END
    , sys.fn_cdc_get_max_lsn()
    , 'all with mask') 
WHERE __$operation <> 1

Consulta modificada [00:01:10]

DECLARE @MinLSN binary(10)
DECLARE @MaxLSN binary(10)
SELECT @MaxLSN= sys.fn_cdc_get_max_lsn()
SELECT @MinLSN=CASE WHEN sys.fn_cdc_increment_lsn(0x00)<sys.fn_cdc_get_min_lsn('dbo_PartitionTest')     
        THEN sys.fn_cdc_get_min_lsn('dbo_PartitionTest')        
        ELSE sys.fn_cdc_increment_lsn(0x00) END

SELECT * 
FROM cdc.fn_cdc_get_net_changes_dbo_PartitionTest(
        @MinLSN, @MaxLSN, 'all with mask') WHERE __$operation <> 1

[Modificado]

Traté de recrear el escenario con una función similar para ver si los parámetros se evalúan para cada fila.

CREATE FUNCTION Fn_Test(@a decimal)RETURNS TABLE
AS
RETURN
(
    SELECT @a Parameter, Getdate() Dt, PartitionTest.*
    FROM PartitionTest
);

SELECT * FROM Fn_Test(RAND(DATEPART(s,GETDATE())))

Pero obtengo el mismo valor para la columna 'Parámetro' para un millón de registros procesados ??en 38 segundos.

¿Fue útil?

Solución

Incluso las funciones escalares deterministas se evalúan al menos una vez por fila. Si la misma función escalar determinista se produce varias veces en la misma '' fila '' con los mismos parámetros, creo que solo entonces se evaluará una vez, p. en un CASO CUANDO fn_X (a, b, c) > 0 ENTONCES fn_X (a, b, c) ELSE 0 END o algo así.

Creo que su problema RAND se debe a que continúa reiniciando:

  

Llamadas repetitivas de RAND () con el   el mismo valor inicial devuelve el mismo   resultados.

     

Para una conexión, si RAND () es   llamado con un valor semilla especificado,   todas las llamadas posteriores de RAND () producen   resultados basados ??en la RAND sembrada ()   llamada. Por ejemplo, la siguiente consulta   siempre devolverá la misma secuencia   de números.

He empezado a almacenar en caché los resultados de la función escalar como usted ha indicado, incluso yendo tan lejos como para precalcular tablas de resultados de la función escalar y unirme a ellas. Eventualmente, se debe hacer algo para que las funciones escalares funcionen. Correcto, la mejor opción es el CLR, aparentemente estos superan con creces las UDF de SQL. Lamentablemente, no puedo usarlos en mi entorno actual.

Otros consejos

En su primera consulta, su fn_cdc_increment_lsn y fn_cdc_get_min_lsn se ejecutan para cada fila. En el segundo ejemplo, solo una vez.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top