2017-05-15 24 views
0

レシートを計算するストアドプロシージャがあります。今日まで、100,000行のデータベースで実行するまで問題はありませんでした。それは遅すぎて、少なくとも3時間稼働し、まだ完了していません。SQL Server 2014ストアドプロシージャが遅い

これを最適化する方法はありますか?ここでは、コード

Declare @sousTotal numeric(16,2), 
    @TotalTx1 numeric(18,4), 
    @TotalTx2 numeric(18,4), 
    @TotalTx3 numeric(18,4), 
    @Taux1 numeric(18,4), 
    @Taux2 numeric(18,4), 
    @Taux3 numeric(18,4), 
    @totalEscompte numeric(16,2), 
    @totalFacture numeric(16,2), 
    @MontantPaiement numeric(16,2) 
Begin 
BEGIN TRANSACTION; 

BEGIN TRY 

    select top 1 @Taux1 = TauxTaxe1,@Taux2 = TauxTaxe2 ,@Taux3 = TauxTaxe3 from tbFactureEntete where ID = @IdFacture and IDCompagnie = @IDCie 
     select @sousTotal =sum(sousTotal),@TotalTx1 = sum(totalTx1),@TotalTx2 = sum(totalTx2),@TotalTx3 = sum(totalTx3), 
    @totalEscompte = sum(totalEscompte),@totalFacture = sum(totalFacture) from(
    select SUM(isnull(A.TotalLigne,0)) AS sousTotal , 
    case taxe1 when 0 then 0 
       when 1 then SUM(isnull(A.TotalLigne,0)) * @Taux1/100 
       end AS totalTx1, 
    case taxe2 when 0 then 0 
       when 1 then SUM(isnull(A.TotalLigne,0)) * @Taux2/100 
       end AS totalTx2, 
    case taxe3 when 0 then 0 
       when 1 then SUM(isnull(A.TotalLigne,0)) * @Taux3/100 
       end AS totalTx3,         
    sum(isnull(MontantEscompte,0)) as totalEscompte ,sum(isnull(TotalLigne,0)) + case taxe1 when 0 then 0 
       when 1 then SUM(isnull(A.TotalLigne,0)) * @Taux1/100 
       end + 
    case taxe2 when 0 then 0 
       when 1 then SUM(isnull(A.TotalLigne,0)) * @Taux2/100 
       end + 
    case taxe3 when 0 then 0 
       when 1 then SUM(isnull(A.TotalLigne,0)) * @Taux3/100 
       end as totalFacture 
    from tbfactureDetail A 
    where IdFacture = @IdFacture and A.IDCompagnie = @IDCie 
    group by taxe1,taxe2,taxe3) as AA 

    select @MontantPaiement = SUM(MontantPaiement) from tbFacturePaiement 
    where IdFacture = @IdFacture 

    update tbFactureEntete 
    set Total_AvantTaxe = @sousTotal, 
     totalTaxe1 = @TotalTx1, 
     totalTaxe2 = @TotalTx2, 
     totalTaxe3 = @TotalTx3, 
     TotalEscompte = isnull(@totalEscompte,0), 
     TotalFacture = isnull(@totalFacture,0), 
     TotalPaiementCR = isnull(@MontantPaiement,0) , 
     TotalSolde = isnull(@totalFacture,0) - isnull(@MontantPaiement,0) 
    where ID = @IdFacture and IDCompagnie = @IDCie 




END TRY 
BEGIN CATCH 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber 
     ,ERROR_SEVERITY() AS ErrorSeverity 
     ,ERROR_STATE() AS ErrorState 
     ,ERROR_PROCEDURE() AS ErrorProcedure 
     ,ERROR_LINE() AS ErrorLine 
     ,ERROR_MESSAGE() AS ErrorMessage; 

    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
END CATCH; 

IF @@TRANCOUNT > 0 
    COMMIT TRANSACTION; 
return 
End 

おかげで再び!

+0

は、あなたがしてクエリを実行しようとした[実行計画?](http://stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan)は – litelite

+0

あなたはロックを確認しましたか? –

+1

**テーブル構造**とは何ですか?あなたのテーブルにはどのような指標がありますか? –

答えて

0

tbfactureDetailテーブルのIdFactureとIDCompagnieのカーディナリティに応じて、索引が存在しない場合は索引が役立ちます。

IDfactureあたり比較的少ないIdCompagnieがある場合IDFacture

CREATE NONCLUSTERED INDEX IX_NewIdx_Name 
    ON tbfactureDetail (IdFacture,IdCompagnie) 

を多くの異なる値に対するIdCompagnie多くの異なる値がある場合は、インクルード使用することができます。

CREATE NONCLUSTERED INDEX IX_NewIdx_Name 
ON tbfactureDetail (IdFacture) 
INCLUDE (IdCompagnie) 

私はこれが数学的には同じで、コードにはもう少し最適だと思います。

BEGIN TRY 

select top 1 @Taux1 = TauxTaxe1 
,   @Taux2 = TauxTaxe2 
,   @Taux3 = TauxTaxe3 
from tbFactureEntete 
where ID = @IdFacture and IDCompagnie = @IDCie 


select @sousTotal =sum(isnull(A.TotalLigne,0)) 
,  @TotalTx1 = sum(taxe1 * isnull(A.TotalLigne,0) * @Taux1/100) 
,  @TotalTx2 = sum(taxe2 * isnull(A.TotalLigne,0) * @Taux2/100) 
,  @TotalTx3 = sum(taxe3 * isnull(A.TotalLigne,0) * @Taux3/100) 
,  @totalEscompte = sum(isnull(MontantEscompte,0)) 
,  @totalFacture = 
sum(taxe1 * isnull(A.TotalLigne,0) * @Taux1/100) + 
sum(taxe2 * isnull(A.TotalLigne,0) * @Taux2/100) + 
sum(taxe3 * isnull(A.TotalLigne,0) * @Taux3/100) 
from tbfactureDetail A 
where IdFacture = @IdFacture and A.IDCompagnie = @IDCie 


select @MontantPaiement = SUM(MontantPaiement) 
from tbFacturePaiement 
where IdFacture = @IdFacture 

update tbFactureEntete 
set Total_AvantTaxe = @sousTotal 
, totalTaxe1  = @TotalTx1 
, totalTaxe2  = @TotalTx2 
, totalTaxe3  = @TotalTx3 
, TotalEscompte = isnull(@totalEscompte,0) 
, TotalFacture = isnull(@totalFacture,0) 
, TotalPaiementCR = isnull(@MontantPaiement,0) 
, TotalSolde  = isnull(@totalFacture,0) - isnull(@MontantPaiement,0) 
where ID = @IdFacture and IDCompagnie = @IDCie 
END TRY 
関連する問題