none
Indici di join. Come ottimizzare questa query? RRS feed

  • Domanda

  •  

    select e.campo1,e.campo2

    from EVENTO e inner join TABELLA t

     

    on e.campoJoin1 between t.[NUM_START]and [NUM_END]

     

    and e.campoJoin2 between t.[DT_START]and t.[DT_END]

     

    where e.campo3>=(SELECT data FROM [TEC_ELAB_LOG]where xxxx='yyyy' and zzzzz='kkkk')
     

     

    and e.campo4='CIAO'

    Ho creato un indice non clustered con quest'ordine: campoJoin1,campoJoin2,campo3,campo4 sulla tabella EVENTO e un indice sulla tabella TABELLA così composto: [NUM_START],[NUM_END],[DT_START],[DT_END].

    Il brutto è che l'indice sulla tabella EVENTO non viene utilizzato, come vedo dall'execution plan.

    Cosa sbaglio? Consigli?

    Grazie, ciao

     

    giovedì 11 agosto 2011 09:44

Risposte

  • Ciao Pasquale,

    Per creare gli indici corretti devi pensare "come farei io, a mano, a recuperare i dati richiesti"? La risposta dipende da molti fattori, in particolare da come quei dati sono distribuiti.

    Un'idea che viene a me, senza conoscere nulla dei dati reali, è che forse comincerei escludendo da Evento tutte le righe che non rispettano la where diretta campo4='ciao'.  L'ideale per me sarebbe quindi disporre di un catalogo ordinato anzitutto per campo4.

    fatto ciò, sempre io e sempre non conoscendo la distribuzione dei dati, mi butterei sulla soluzione di campo3, se quindi i dati all'interno del mio indice fossero organizzati per campo4, campo3 sarei a cavallo.

    Bene, ora potrei per ogni valore campojoin1 2 campojoin2 cercare una corrispondenza in TABELLA, potrei procedere più veloce se quei dati fossero ordinati, almeno per Num_Start, Num_End.

    Io potrei anche procedere ora, se non fosse che per lavorare avrò bisogno anche dei valori campojoin1, campojoin2, campo1, campo2, DT_START e  DT_END che, se non sono inclusi nell'indice mi richiedono nuove fastidiose ricerche sui cataloghi "originali".

    In definitiva io per eseguire quella query a mano gradirei avere a disposizione gli indici:

    create index i1 on EVENTO(campo4, campo3) include(campo1,campo2, campoJoin1, campoJoin2)
    create index i1 on TABELLA(NUM_START, NUM_END) include(DT_START,DT_END)
    

    Prova a passarli a Sql, forse ragiona un po' come me :-)

    marc.

    giovedì 11 agosto 2011 15:16