2012-11-21 11 views
7

Ho riscontrato un problema con le prestazioni di ordinazione nel mio database SQL Server 2005. Diciamo che ho la seguente query:SQL Server 2005 che esegue la tabella completa Ordina prima della scansione dell'indice

select 
    id, versionId, orderIndex 
from Forms_Page 
where 
    versionId = 'AFCF4921-31B4-44C1-B3A7-913910F7600E' 
order by 
    orderIndex 

Questa query restituirà 7 righe e prendere ~ 23 secondi per l'esecuzione. Il piano di esecuzione di questa query è il seguente (non è ancora possibile inviare immagini):

selezionare (costo: 0%) -> Ordina (costo: 11%) -> Scansione di indice cluster (costo: 89%)

Se rimuovo la clausola 'order by', la query verrà completata in ~ 4 ms, come previsto.

Perché SQL Server esegue un ordinamento prima di ottenere le righe richieste? Non ha senso per me. Perché non ottenere prima le 7 righe e ordinare solo quelle? Mi manca qualcosa, come una configurazione del database, o si tratta di un comportamento previsto?

Potrei usare una selezione interna, come la seguente, per forzare il motore a ottenere prima le righe e poi ordinare, il che restituirebbe le righe in ~ 6 ms, ma poiché stiamo usando l'EF questo non sarebbe una buona soluzione per noi (potremmo ordinare i risultati in memoria, ma stiamo usando le opzioni LoadWith per alcune delle entità che generano codice SQL con ordinamenti e che anche il codice sta soffrendo dello stesso problema 'ordine per').

select * 
from(
    select 
     id, versionId, orderIndex 
    from Forms_Page 
    where 
     versionId = 'AFCF4921-31B4-44C1-B3A7-913910F7600E' 
) T 
order by 
    T.orderIndex 

ho provato un po 'di indicizzazione è le colonne ordinate, che fissati cosa, ma solo perché le colonne sono già ordinati. Sembra una soluzione goffa ...

+0

L'ordine dei passaggi Clustered Index Scan -> Ordina -> Select. La selezione di ciò che vedi è l'ultimo passaggio, che fornisce esattamente l'output previsto. (e l'output dovrebbe essere ordinato) E nel piano il "compito più grande" stimato è la scansione dell'indice e non l'ordinamento. Sei sicuro che senza l'ordine del piano di esecuzione si utilizzi lo stesso indice per la scansione? –

+0

Sì, usa lo stesso indice perché, ma qualcosa che ho capito, ora che hai menzionato, è che per una semplice ricerca usa IMPLICIT_CONVERT per convertire la stringa in un identificatore univoco mentre nell'ordine sta usando {guid, 'AFCF4921- 31B4-44C1-B3A7-913910F7600E '}. Ho fatto alcuni test con i cast e le conversioni e continuo a ricevere gli stessi orari. –

+0

VersionId è una chiave univoca? O puoi avere duplicati? Se è unico mi aspetterei che sia molto più veloce. –

risposta

1

In primo luogo, non so perché lo stia facendo! Detto questo, ecco un paio di cose che probabilmente hai già provato.

Infine, e forse non rilevante nel tuo caso, ma c'è una buona spiegazione della tabella allude qui: http://blog.sqlauthority.com/2009/11/19/sql-server-understanding-table-hints-with-examples/

+0

Purtroppo, nessuno di questi ha funzionato e nemmeno con HINTS, non penso sia possibile dire a Entity Framework di usarli, per quanto ne so. –

+0

Questo è estremamente strano! Ho appena eseguito EXEC sp_updatestats e non funziona correttamente. È strano che non abbia funzionato la prima volta! Ma ciò che conta ora sta funzionando! Grazie per l'aiuto! –

+0

Questo è bizzarro, ma interessante che alla fine ha funzionato bene. Farò una nota per aggiornare le statistiche due volte se non sembra funzionare la prima volta ;-) –

Problemi correlati