2016-06-07 75 views
0

我在添加索引后遇到了SQL查询中的一个大问题。索引转SQL查询太慢

declare @DateFromCT date, @DateToCT date; 
declare @DateFromCT2 date, @DateToCT2 date; 
set dateformat dmy; 
set @DateFromCT= '1/1/2015'; set @DateToCT= '31/3/2015'; 
set @DateFromCT2= '1/4/2015'; set @DateToCT2= '30/4/2015'; 
Select distinct CT.CodCliente,ct.codacesso FROM CT_Contabilidade CT 
Inner join CD_PlanoContas PC ON CT.CodAcesso = PC.Cod 
WHERE NOT exists (
    SELECT 1 FROM ct_contabilidade CT2 
    WHERE CT2.CodAcesso = CT.CodAcesso 
    and CT2.Data between @DateFromCT2 and @DateToCT2 
    And (CT2.CodEmpresa = 1) And CT2.codcliente = ct.codcliente ) 
and CT.Data between @DateFromCT and @DateToCT 
AND PC.subgrupo = 'C' 
And (CT.CodEmpresa = 1) And ct.codCliente > 0 

CT_Contabilidade的PK是Sequential(bigint标识)聚簇索引。 它有150万条记录。

没有其他非聚集索引,它表现良好,花费少​​于1秒。没关系对我来说。

我在CodAcesso上创建一个索引以匹配CD_PlanoContas key (cod); CD_PlanoContas PK(聚集索引)是Cod。

它仍然表现不错。无显着差异...

所以我创建过一个codCliente指数(因为它也涉及其他表)

...而在这之后,查询速度太慢;它需要7或8分钟。

  • 如果我放弃CodAcesso索引,它就会变好。
  • 如果我放弃CodCliente索引,也可以。
  • 如果我让他们两个,但改变查询,采用与CD_Planocontas(因此,过滤器“AND PC.subgrupo ='C'”)的内部联接,它是确定的。

我无法想象索引导致查询行为的方式。

这是一个巨大的差异,而不仅仅是“性能损失”。我尝试了其他的一些东西,比如拿出每个过滤器......没有改变。

执行计划建议指标:

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>] 
ON [dbo].[CT_Contabilidade] ([CodEmpresa],[Data],[CodCliente]) 
INCLUDE ([CodAcesso]) 

我创造了它,和查询工作正常,甚至与其他2个指数(codCliente和codAcesso)

但我不喜欢为此查询创建一个特定的索引(这只是使用这些表的许多查询中的一个)。

如果运行良好而没有索引,我认为它应该至少与这2个索引相等。

是什么原因导致性能发生如此剧烈的变化?我需要改变以加快速度?

回答

0

遵循执行计划的建议并不总是好主意。

我建议你在添加索引之前和之后比较执行计划并查看差异。也许这个索引会导致SQL引擎选择一个糟糕的计划。

也尝试更新您的表和索引的统计数据,看看如何影响。

+0

yeap,SQL Server真的选择了一个坏计划。我必须提示索引子查询(在“EXISTS”之后)以强制查询使用PK_CT_Contabilidade,而不是非聚簇索引。 – jcosti82

1

尝试使用索引优化器提示来控制正在使用的索引。

例如:

SELECT * 从与(指数(titleind))标题 其中标题= '美食家微波'

使用 '设置统计上io的' 命令来查看的数量使用每个查询/索引组合扫描页面并使用'rightclick/show execution plan'选项来查看查询的执行方式

+0

我试过强制查询使用pk(聚簇索引)。它工作正常。即使现有的两个索引(codAcesso和codCliente),查询过程都运行良好(小于1秒)。 问题是:我认为查询优化器应该选择正确的索引。如果同时存在两个索引(codCliente和CodAcesso),而不是“暗示”查询使用PK(在ct_contabilidade上),则需要超过7分钟。 我只想了解发生了什么,以防止这样的未来问题。 – jcosti82