缺少索引(Impact 97):创建非聚簇索引

时间:2017-06-28 14:55:24

标签: sql-server

我正在尝试优化我的存储过程。当我查看查询计划时,我可以看到tempcompany上的tablescan显示为97%。我还看到以下消息缺少索引(Impact 97):在#tempCompany上创建非聚集索引 我已经设置了非聚集索引。有人可以指出问题是什么

 if object_id('tempdb..#tempCompany') is not null drop table #tempCompany else  

        select

            fp.companyId,fp.fiscalYear,fp.fiscalQuarter,fi.financialperiodid, fi.periodEndDate,
            fc.currencyId,fp.periodtypeid,ROW_NUMBER() OVER (PARTITION BY fp.companyId, 
            fp.fiscalYear, fp.fiscalQuarter ORDER BY fi.periodEndDate DESC) rowno   

        into #tempCompany               

        from 

            ciqFinPeriod fp

            inner join #companyId c on c.val = fp.companyId

            join ciqFinInstance fi on fi.financialperiodid = fp.financialperiodid

            join ciqFinInstanceToCollection ic on ic.financialInstanceId = fi.financialInstanceId

            left  join ciqFinCollection fc on fc.financialCollectionId = ic.financialCollectionId

            left join ciqFinCollectionData fd on fd.financialCollectionId = fc.financialCollectionId

        where 

            fp.periodTypeId = @periodtypeId

            and fi.periodenddate >= @date

            --and fp.companyId in (select val from @companyId)

            CREATE NONCLUSTERED INDEX id_companyId2 on #tempCompany(companyId,fiscalYear,fiscalQuarter,financialperiodid,periodEndDate,currencyId,periodtypeid,rowno)  



 if object_id('tempdb..#EstPeriodTbl') is not null drop table #EstPeriodTbl else    

    select

        companyId,fiscalYear,fiscalQuarter,financialPeriodId,periodenddate,currencyId,
        periodtypeid,rowno

    into #EstPeriodTbl

    from #tempCompany a

    where a.rowno = 1

    order by companyid, periodenddate

    CREATE NONCLUSTERED INDEX id_companyId3 on #EstPeriodTbl(companyId,periodenddate,fiscalYear,fiscalQuarter,currencyId,financialPeriodId,rowno)     

   Execution Plan

enter image description here

2 个答案:

答案 0 :(得分:1)

您无需在 #tempCompany 索引中包含所有内容;只是 rowno

CREATE NONCLUSTERED INDEX id_companyId2 on #tempCompany(rowno)

答案 1 :(得分:1)

简短回答:您提供的索引在您正在进行的查询中无法帮助SQL Server。如果您创建另一个非聚集索引,并且rowno作为索引中的第一列,则Sql Server可能会使用该索引。

长期探索: 您遇到问题的原因是因为您创建的索引对于具有此特定查询的SQL Server并不有用。记录在索引上排序的顺序由您在创建索引时指定的顺序确定。

(例如,您的索引首先按照companyId对您的记录进行排序,然后按照其financialYear,然后按其财务季度对同一companyId的记录进行排序。)

尝试使用提供的索引通过它的rowno值来查找项目,就像您尝试根据某人的电话号码查找电话簿中的条目一样。找到所有匹配记录的唯一方法是搜索书中的每个记录(即表扫描)。

通常,只有当您在where子句中使用的信息与索引中的第一列匹配时,您才可以使用非聚簇索引(即,如果您可以在where子句中为companyId提供SARGable谓词,则可以使用此指数)

再次使用电话簿:如果我给你一个姓氏和电话号码,现在你不再需要对电话簿进行全表扫描,你可以对姓氏进行索引扫描。哪个会更有效率。如果您能够提供姓氏和名字,然后是中间的初始和电话号码,您可以进行更高效的表格扫描。但是,如果我只提供姓氏,中间名字和电话号码;现在我回到仅仅使用姓氏的值来扫描索引。

因此,如果您可以缩小记录集以至少使用companyId(即在where子句中使用companyID),则可以使用您提供的索引。

或者,我想这就是你想要做的,创建一个按rowno,然后companyIdperiodendDate排序的索引。

e.g。

CREATE NONCLUSTERED INDEX idx_temp_rowno ON #tempCompany(rowno, companyId, periodenddate)