Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    [SQL SERVER 2008] IF EXISTS (STATEMENT) lento rispetto esecuzione del solo STATEMENT

    Buongiorno a tutti.

    Ho un trigger che cerca di forzare una regola la quale impone che un certo record non abbia doppioni in un certo range di tempo.

    In altre parole ho una tabella T con i campi (C1,C2,C3,RangeStart,RangeEnd,C4,C5...,CN), voglio forzare la regola seguente:


    Non possono esistere due record con identici C1,C2,C3 per i quali ci sia una sovrapposizione di date di validità


    Esempio

    Se la tabella contiene un record con Range Start '2012-01-01', Range End '2012-01-31' e l'utente vuole inserire un nuovo record con C1,C2,C3 identici al precedente record ma con Range Start = '2012-02-01',Range End='2012-02-29' l'inserimento va a buon fine, se invece l'utente inserisce un record con RangeStart='2011-12-20',RangeEnd='2012-01-14' l'inserimento fallisce perchè il range di date di questo record si sovrappone per 14 giorni al record già esistente.


    Ho quindi creato la vista V_DOPPIONI che restituisce tutti i records che violano la regola di cui sopra.

    Nella tabella T ho aggiunto il seguente trigger

    codice:
    CREATE TRIGGER [dbo].[T_NO_DOPPIONI]
       ON T
       FOR INSERT, UPDATE 
    AS 
    BEGIN
    	
        SET NOCOUNT ON
    
        IF EXISTS ( SELECT * FROM  V_DOPPIONI ) 
        BEGIN
            RAISERROR('CANNOT HAVE SAME VALUES OVERLAPPING DATETIME RANGES, PLEASE CHECK DATE AND TIME RANGES', 16,1)
            ROLLBACK
        END		
    END
    
    Il tempo di escuzione del trigger è inaccettabile.

    Il problema è che la vista V_DOPPIONI ritorna in tempo zero, aggiungendo IF EXISTS il tempo di esecuzione supera i 40 secondi, mi chiedo come sia possibile, dal momento che nel peggiore dei casi il motore di database dovrebbe metterci un nanosecondo in piu rispetto al caso dell'esecuzione completa della query.

    Per riepilogare il mio problema attuale è il seguente:

    codice:
    SELECT  * FROM v_doppioni --tempo esecuzione 0 secondi
    
    IF EXISTS(SELECT * FROM v_doppioni) BEGIN PRINT 'ESISTONO DOPPIONI' END -- 40 secondi e oltre.
    Quale costrutto alternativo posso utilizzare per imporre la condizione di cui sopra alla mia tabella T o in alternativa come posso fare a rendere veloce la clausola IF EXISTS?

    Grazie a tutti.

  2. #2
    Per futura memoria: in generale non sono riuscito a capire per quale motivo la query

    SELECT * FROM v_doppioni --tempo esecuzione 0 secondi

    mentre

    IF EXISTS(SELECT * FROM v_doppioni) BEGIN PRINT 'ESISTONO DOPPIONI' END -- 40 secondi e oltre.

    Nel frattempo ho scoperto che

    SELECT TOP 1 * FROM v_doppioni --tempo esecuzione 40 secondi

    evidentemente qualcosa nell'ottimizzatore non riesce a ottimizzare come si deve (indici e statistiche perfettamente aggiornati)

    Il workaround da me utilizzato è stato il seguente

    codice:
    DECLARE @ViolatingRecords INT
    		
    		SELECT  @ViolatingRecords = IDRecord  FROM dbo.V_DOPPIONI
    		IF @ViolatingRecords IS NOT NULL
    		BEGIN
    			RAISERROR('PLEASE CHECK TIME RANGES', 16,1)
    			ROLLBACK
    		END

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.