Domanda

Le seguenti query richiedono rispettivamente 70 minuti e 1 minuto su una macchina standard per 1 milione di record. Quali potrebbero essere le possibili ragioni?

Query [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

Query modificata [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

[Modificato]

Ho provato a ricreare lo scenario con una funzione simile per vedere se i parametri sono valutati per ogni riga.

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())))

Ma sto ottenendo lo stesso valore per la colonna "Parametro" per un milione di record elaborati in 38 secondi.

È stato utile?

Soluzione

Anche le funzioni scalari deterministiche vengono valutate almeno una volta per riga. Se la stessa funzione scalare deterministica si verifica più volte sulla stessa "riga" con gli stessi parametri, credo che solo allora verrà valutata una volta - ad es. in un CASO QUANDO fn_X (a, b, c) > 0 THEN fn_X (a, b, c) ELSE 0 END o qualcosa del genere.

Penso che il tuo problema RAND sia dovuto al fatto che continui a ridimensionare:

  

Chiamate ripetitive di RAND () con il   lo stesso valore seme restituisce lo stesso   risultati.

     

Per una connessione, se RAND () è   chiamato con un valore seme specificato,   tutte le successive chiamate di RAND () producono   risultati basati sul seme RAND ()   chiamata. Ad esempio, la seguente query   restituirà sempre la stessa sequenza   di numeri.

Ho preso in considerazione la memorizzazione nella cache dei risultati delle funzioni scalari, come hai indicato, anche arrivando al punto di precalcolare le tabelle dei risultati delle funzioni scalari e di unirmi a loro. Qualcosa deve essere fatto alla fine per far funzionare le funzioni scalari. Altrimenti, l'opzione migliore è il CLR - apparentemente questi UDF SQL superano di gran lunga. Sfortunatamente, non posso usarli nel mio ambiente attuale.

Altri suggerimenti

Nella prima query, fn_cdc_increment_lsn e fn_cdc_get_min_lsn vengono eseguiti per ogni riga. Nel secondo esempio, solo una volta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top