Couvrir l'index et se débarrasser de Key Lookup

J'ai une instruction SQL qui me donne une search de key en suçant le traitement de cette requête ci-dessous. Depuis sa partie d'une union en trois parties, se débarrasser de la search de key est préférable.

Ma requête est ci-dessous.

SELECT c.customerName, c.customerNumber, totals.TotalLoanAmount, totals.TotalCommitmentAmount, l.loanNumber, l.commitmentAmount, ed.amountThreshold, ex.exceptionId, IsNull(ex.reminderDateGracePeriod, ed.defaultReminderDateGracePeriod) AS gracePeriod, ex.reminderDate AS targetDate, IsNull(ex.exceptionState, 'N') AS exceptionState, ex.exceptionState AS GeneralExceptionState FROM exceptionDefinition AS ed INNER JOIN exception AS ex ON ed.exceptionDefId = ex.exceptionDefId AND ex.loanId IS NULL INNER JOIN customer AS c ON c.customerId = ex.customerId LEFT OUTER JOIN loan AS l ON l.loanId = ex.loanId INNER JOIN viewCustomerLoanTotals AS totals ON totals.customerId = c.customerId WHERE ed.requireReminderDate = 'Y' AND ex.statusType = 'required' 

J'ai essayé de définir un index de couverture pour cela en faisant une search de key sur l'index Clustered sur la key primaire de la table d'exception.

ExceptionId

C'est mon index de couverture sur les colonnes sélectionnées avec le statusType comme partie de la clause where.

 CREATE NONCLUSTERED INDEX [IX_EXCEPTIONPROCESS_COVER] ON [dbo].[exception] ( [exceptionId] ASC, [loanId] ASC, [reminderDate] ASC, [reminderDateGracePeriod] ASC, [exceptionState] ASC ) INCLUDE ([statusType]) ON [PRIMARY] 

Cela n'a aucun effet sur la search de key du tout. J'ai essayé de le forcer à utiliser l'index, mais il devient une ressource de 91% plutôt que les 61% dont j'essaie de me débarrasser.

Plan de traitement

Toute idée serait géniale

Le problème est que votre index ne peut pas vraiment être utilisé pour la jointure. Pour être utilisable, le premier champ (s) dans l'index doit être tel que vous joignez aussi la table avec (ou existe dans la clause where).

 INNER JOIN exception AS ex ON ed.exceptionDefId = ex.exceptionDefId AND ex.loanId IS NULL 

Vous joignez les tables avec exceptionDefId (+ loanID), mais l'index n'a pas cela:

 CREATE NONCLUSTERED INDEX [IX_EXCEPTIONPROCESS_COVER] ON [dbo].[exception] ( [exceptionId] ASC, [loanId] ASC, ... 

Si cet index uniquement pour ce SQL, alors devrait mieux fonctionner:

 CREATE NONCLUSTERED INDEX [IX_EXCEPTIONPROCESS_COVER] ON [dbo].[exception] ( exceptionDefId, loanId, statusType ) include ( exceptionId, reminderDateGracePeriod, reminderDate, exceptionState, customerId ) 

L'ordre des champs dans l'index doit également être basé sur la sélectivité (= qui a less de lignes en moyenne par key). Pour inclure les champs qui n'a pas d'importance.

Vous obtenez une ligne et vous essayez d'optimiser la requête. Le 61% (où presque tout le travail de cette requête est en cours) est relatif à l'set du plan de requête pour la requête. Il y a une limite quant à combien vous pouvez pousser. – Le moteur SQL Server n'effectue qu'un travail limité (optimization d'une requête) car il en vaut la peine et considère que votre requête ne vaut pas la peine d'y consacrer beaucoup d'efforts.

Votre index "couvrant" n'inclut pas toutes les colonnes qui sont utilisées de cette table selon la "list de sortie". Ajoutez les colonnes restantes.