Sql server 覆盖索引和摆脱键查找

Sql server 覆盖索引和摆脱键查找,sql-server,indexing,key,Sql Server,Indexing,Key,我有一个SQL语句,它为我提供了一个键查找,它吸收了下面这个查询的处理过程。因为它是由3部分组成的联合体的一部分,所以最好不要使用键查找 我的问题如下 SELECT c.customerName, c.customerNumber, totals.TotalLoanAmount, totals.TotalCommitmentAmount, l.loanNumber, l.commitmentAmount, ed.amountThreshold, e

我有一个SQL语句,它为我提供了一个键查找,它吸收了下面这个查询的处理过程。因为它是由3部分组成的联合体的一部分,所以最好不要使用键查找

我的问题如下

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'
我尝试为此设置覆盖索引,因为它在异常表的主键上的聚集索引上执行键查找

例外情况

这是我选择的列的覆盖索引,statusType作为where子句的一部分

CREATE NONCLUSTERED INDEX [IX_EXCEPTIONPROCESS_COVER] ON [dbo].[exception]
(
    [exceptionId] ASC,
    [loanId] ASC,
    [reminderDate] ASC,
    [reminderDateGracePeriod] ASC,
    [exceptionState] ASC
)
INCLUDE ([statusType]) ON [PRIMARY]
INNER JOIN exception AS ex ON 
    ed.exceptionDefId = ex.exceptionDefId AND 
    ex.loanId IS NULL
这对密钥查找没有任何影响。我试图强迫它使用索引,但它变成了91%的资源,而不是我试图摆脱的61%


任何洞察都会很好

您得到的是一行,并且您正在尝试优化查询。61%(几乎完成了此查询的所有工作)是相对于查询的整个查询计划的。你能推多少是有限制的SQL Server引擎只投入它认为值得投入的工作(优化查询),它将您的查询视为不值得投入大量精力的事情

问题是您的索引不能真正用于连接。要使其可用,索引中的第一个字段必须使您也与表连接(或存在于where子句中)

您正在使用exceptionDefId(+loanID)连接表,但索引没有:

CREATE NONCLUSTERED INDEX [IX_EXCEPTIONPROCESS_COVER] ON [dbo].[exception]
(
    [exceptionId] ASC,
    [loanId] ASC,
...
如果此索引仅用于此SQL,则应能更好地工作:

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

索引中字段的顺序也应基于选择性(=每个键的平均行数最少的字段)。对于不重要的包含字段。

根据“输出列表”,您的“覆盖”索引不包括该表中正在使用的所有列。添加其余列。

非常感谢。这很有效。非常感谢您的指数见解。