Date un'occhiata a questo violino: http://sqlfiddle.com/#!6/18324/2SQL Server utilizza la scansione invece di cercare quando si utilizza una funzione di finestra e predicato contiene una variabile
Espandere il primo piano di esecuzione, per le query vista B
.
Si noti che la prima query viene eseguita utilizzando index seek, mentre la seconda esegue l'index scan. Nella mia configurazione reale, con migliaia di righe, questo produce un impatto sulle prestazioni che è piuttosto considerevole.
WTF ???
Le query sono equivalenti, vero? Perché una ricerca letterale cerca e una scansione variabile?
Ma ancora più importante: come posso aggirare questo?
This post arriva più vicino al problema e la soluzione che funziona da lì utilizza option(recompile)
(grazie, Martin Smith). Tuttavia, questo non funziona per me, perché le mie query vengono generate dalla mia libreria ORM (che è Entity Framework) e non posso modificarle manualmente.
Piuttosto, quello che sto cercando è un modo per riformulare la vista B
in modo che il problema non si verifichino.
Mentre si scherza con questo problema, ho notato che è sempre il blocco "Segmento" nel piano di esecuzione che perde il predicato. Per verificare ciò, ho riformulato la query in termini di una sottoquery con la funzione min
(vedere la vista D
). E voilà! - entrambe le query sulla vista D
producono piani identici.
La cattiva notizia, tuttavia, è che non posso usare questa min
trucco -powered, perché nella mia vera messa a punto, la colonna Y
è in realtà diverse colonne, in modo che posso ordinare da loro, ma non riesco a prendere un min()
di loro.
Quindi la seconda domanda sarebbe: qualcuno può inventare un trucco simile alla subquery con alimentazione minima, ma funziona per più colonne?
NOTA 1: questo non è assolutamente correlato al punto di non ritorno, perché ci sono solo 2 record nella tabella.
NOTA 2: non ha nemmeno a che fare con la presenza di una vista. Guarda un esempio con la vista C
: il server sta usando felicemente la ricerca in quel caso.
Sulla mia istanza R2 2008 locale 'selezionare * da B dove X = @a opzione (ricompilare)' produce una ricerca. –
@ Martin Smith: Giusto. Mi è mancato. Grazie. Sfortunatamente, tuttavia, questo non funziona. Vedi il mio aggiornamento alla domanda. –
Molto probabilmente un duplicato: http://dba.stackexchange.com/questions/12498/window-functions-cause-awful-execution-plan-when-called-from-a-view-with-externa – GSerg