none
stored con molte cte... select non va a buon fine RRS feed

  • Domanda

  • Ciao a tutti!

    Ho un problema con una stored (per me) piuttosto complessa su SQL Server 2005.

    Per giungere al mio scopo ho utilizzato una serie di espressioni di tabella comuni (CTE).

    ;WITH T1 AS
    (
     SELECT ...
    ), T2 AS
    (
     SELECT ...
    ), T3 AS
    (
     SELECT ...
    ), T4 AS
    (
     SELECT...
    ), T5 AS
    (
     SELECT...
    )
    
    INSERT INTO TMP_TABELLA_FATTURE_DETTAGLI
    (
     ...
    )
    
    SELECT 
    ...
    
    FROM 
    TMP_TABELLA_FATTURE_TESTATE
    
    LEFT JOIN
    T5
    ON
    ...

    Il problema risiede nella 'SELECT' della CTE chiamata 'T5': i tempi di esecuzione sono infiniti.
    Il codice t-SQL della SELECT è piuttosto semplice:

    SELECT
    Z1.FIELD_01,
    Z1.FIELD_02,
    Z1.FIELD_03,
    Z1.FIELD_04,
    ISNULL(Z2.FIELD_05, 0) FIELD_05
    
    FROM
    T3 Z1
    
    LEFT JOIN
    T4 Z2
    ON
    Z2.FIELD_02 = Z1.FIELD_02
    AND Z2.FIELD_03 = Z1.FIELD_03

    Se scrivo JOIN al posto di LEFT JOIN, ottengo i risultati in circa 12 secondi. 
    Ho provato a usare la funzione CAST in questo modo...

    LEFT JOIN
    T4 Z2
    ON
    CAST(Z2.FIELD_02 AS VARCHAR(5)) = CAST(Z1.FIELD_02 AS VARCHAR(5))
    AND CAST(Z2.FIELD_03 AS INT) = CAST(Z1.FIELD_03 AS INT)

    Ma non ottengo alcun effetto. La soluzione, per me, è stata di scrivere la SELECT finale in questo modo:

    SELECT
    ...
    
    FROM
    TMP_ORDER_HEADERS
    
    LEFT JOIN
    T5
    ON
    ...
    
    OPTION ( FORCE ORDER, HASH JOIN )
    Ho aggiunto la linea:

    OPTION ( FORCE ORDER, HASH JOIN )

    Adesso la procedura si prende solo 15 secondi per essere eseguita interamente. Non chiedetemi perchè, non sono un mago nella lettura dei query plan... 
    Potreste aiutarmi a capire? 
    Esiste una soluzione migliore?

    Grazie!
    Lamarmora

    • Modificato lamarmora domenica 22 giugno 2014 21:31
    giovedì 19 giugno 2014 22:03

Risposte

  • Ciao,

    per come l'hai descritta, potrebbe trattarsi di oggetti con tante righe, per cui se al posto di LEFT fai la INNER JOIN, riduci il set, e non di poco. Purtroppo con quello che indichi è molto difficile capire il tuo problema reale. Bisognerebbe conoscere molte più cose per fare tuning di quella query. Servono analisi sulla macchina, numero di record di ogni oggetto, eventuali indici creati, piani di esecuzione. Con quanto scrivi risulta veramente complesso aiutarti.


    Alessandro Alpi SQL Server MVP

    • Contrassegnato come risposta lamarmora martedì 1 luglio 2014 09:35
    lunedì 30 giugno 2014 09:13
    Moderatore

Tutte le risposte

  • Ciao,

    per come l'hai descritta, potrebbe trattarsi di oggetti con tante righe, per cui se al posto di LEFT fai la INNER JOIN, riduci il set, e non di poco. Purtroppo con quello che indichi è molto difficile capire il tuo problema reale. Bisognerebbe conoscere molte più cose per fare tuning di quella query. Servono analisi sulla macchina, numero di record di ogni oggetto, eventuali indici creati, piani di esecuzione. Con quanto scrivi risulta veramente complesso aiutarti.


    Alessandro Alpi SQL Server MVP

    • Contrassegnato come risposta lamarmora martedì 1 luglio 2014 09:35
    lunedì 30 giugno 2014 09:13
    Moderatore
  • Ciao Alessandro, intanto grazie mille per la risposta! Per adesso mi accontento della mia soluzione

    OPTION ( FORCE ORDER, HASH JOIN )

    visto che i risultati sono corretti e i tempi accettabili, la mia era più che altro curiosità, se in futuro avrò modo di approfondire ne riparleremo...

    Saluti!

    Pileggi

    martedì 1 luglio 2014 09:35