2017-06-28 142 views
0

我想优化我的存储过程。当我查看查询计划时,可以看到tempcan上的桌面扫描显示97%。我也看到以下消息缺少索引(影响97):在#tempCompany上创建非聚簇索引 我已经设置了非聚簇索引。可能有人指出的问题是什么缺少索引(影响97):创建非聚集索引

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

显示你的代码的一部分,你选择从'#tempCompany' –

+2

和完整的缺少索引警告。 –

+2

问题是您在Select/Into语句后创建索引。这就是为什么它抱怨缺少索引。在插入之前创建表和索引。 –

回答

0

你并不需要包括在#tempCompany所有内容建立索引;只是rowno

CREATE NONCLUSTERED INDEX id_companyId2 on #tempCompany(rowno) 
0

简短的回答:您所提供的指数,不利于SQL Server中的你正在做的查询。如果您创建另一个非聚集索引,并且将rowno作为索引中的第一列,那么Sql Server可能会使用该索引。

Long explination: 您遇到问题的原因是因为您创建的索引对具有此特定查询的SQL Server无用。记录在索引中排序的顺序取决于您在创建索引时指定的顺序。

(例如你的指数令你的记录由companyId,然后再由他们fiscalQuarter通过fiscalYear订单相同companyId的记录,然后。)

试图使用所提供的指数,以找到一个项目只是它的rowno价值,就像你试图根据某人的电话号码找到电话簿中的条目。找到所有匹配记录的唯一方法是搜索书中的每条记录(即表扫描)。

一般而言,只有当您在where子句中使用的信息与您的索引中的第一列匹配时(例如,如果您可以在where子句中为companyId提供一个SARGable谓词,则可以使用非聚集索引这个索引)

再次使用电话簿:如果我给了你一个姓氏和一个电话号码,现在你不再需要在电话簿上进行全表扫描,你可以对最后一次进行索引扫描名称。哪一个会更有效率。如果您能够提供姓氏,名字,中间首字母和电话号码,则可以进行更有效的表扫描。但如果我只给你提供姓氏,中间名字和电话号码;现在我回过头来看看索引上的姓氏的价值。

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

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

例如

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