2016-06-07 80 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