3

select ステートメント ( 5000 レコード) を作成するストアド プロシージャがあります。select ステートメント内で、テーブル値関数を呼び出します。テーブル値関数は、いくつかの集計計算を実行します

結果を返すのに 1 分以上かかる

ここに集計関数コードがあります

ALTER FUNCTION [dbo].[GetParticipationEvaluation](@Participation_ID int)
RETURNS @TabEvaluation TABLE (
   JudgeCount               int      NOT NULL,
   JudgeEvaluationCount     int     NOT NULL,
   Evaluation               float
) AS BEGIN declare @JudgeCount int declare @JudgeEvaluationCount int declare @Evaluation float SELECT @JudgeCount=COUNT(*),@Evaluation= AVG(Evaluation) from Judge_Participation where Participation_ID=@Participation_ID and Sys_Is_Active=1 and status_ID =2 SELECT @JudgeEvaluationCount=COUNT(*),@Evaluation= AVG(Evaluation) from Judge_Participation where Participation_ID=@Participation_ID and Sys_Is_Active=1 INSERT INTO @TabEvaluation (JudgeCount, JudgeEvaluationCount, Evaluation) select @JudgeCount,@JudgeEvaluationCount,@Evaluation RETURN; END;
これはストアドプロシージャコードです
ALTER procedure [dbo].[GetEvalutionStatistics]
as
select  [Participation].[Participation_ID]
    ,[Participation].[Name_Ar]
    ,[Participation].[Name_En]
    ,[Participation].[Is_Submitted]
    ,[Participation].[Student_ID]
    ,[Participation].[Result_ID]
    ,[Participation].[Field_ID]
    ,[Participation].[Category_ID]
    ,[Participation].[Actual_Field_ID]
    ,[Participation].[Current_Member_ID]
    ,[Participation].[Sys_Is_Active]
    ,[Participation].[Turnitin_Value]
    ,[Participation].[Turnitin_Link]
    ,Eval.JudgeCount
    ,Eval.JudgeEvaluationCount
    ,Eval.Evaluation
    ,[Actual_Field_ID].[Name_Ar] as 'Actual_Field_ID.Name_Ar'
    ,[Actual_Field_ID].[Name_En] as 'Actual_Field_ID.Name_En'
    ,[Result_ID].[Name_Ar] as 'Result_ID.Name_Ar'
    ,[Result_ID].[Name_En] as 'Result_ID.Name_En'
    --,dbo.getjudgecount(participation_ID,null) 'JudgeCount'
    --,dbo.getjudgecount(participation_ID,2) 'JudgeEvaluationCount'
    --,dbo.GetAvgParticipationEvaluation(Participation_ID) 'Evaluation'
    --,dbo.getParticipationSpecialist(Participation_ID) as 'specialist'
from [Participation] 
    left join [Participation_Field_List] as [Actual_Field_ID] on [Actual_Field_ID].[Field_ID]=[Participation].[Actual_Field_ID]
    left join [Participation_Result] as [Result_ID] on [Result_ID].[Result_ID]=[Participation].[Result_ID]
OUTER APPLY dbo.GetParticipationEvaluation([Participation].participation_ID) Eval
where 
     participation.Sys_Is_Active=1 and participation.is_submitted=1
このパフォーマンスの悪さを引き起こしている部分を知りたい

4

4 に答える 4

1

通常、「列の結合」と「where句」にインデックスが必要です。実行プランを取得して、インデックスが欠落していないかどうかを確認してください。

于 2013-03-20T07:47:38.057 に答える
1

遅い機能なしでこの手順を試してください

CREATE procedure [dbo].[GetEvalutionStatistics]
as
select  p.[Participation_ID]
    ,p.[Name_Ar]
    ,p.[Name_En]
    ,p.[Is_Submitted]
    ,p.[Student_ID]
    ,p.[Result_ID]
    ,p.[Field_ID]
    ,p.[Category_ID]
    ,p.[Actual_Field_ID]
    ,p.[Current_Member_ID]
    ,p.[Sys_Is_Active]
    ,p.[Turnitin_Value]
    ,p.[Turnitin_Link]
    ,Eval.JudgeCount
    ,Eval.JudgeEvaluationCount
    ,Eval.Evaluation
    ,[Actual_Field_ID].[Name_Ar] as 'Actual_Field_ID.Name_Ar'
    ,[Actual_Field_ID].[Name_En] as 'Actual_Field_ID.Name_En'
    ,[Result_ID].[Name_Ar] as 'Result_ID.Name_Ar'
    ,[Result_ID].[Name_En] as 'Result_ID.Name_En'
    --,dbo.getjudgecount(participation_ID,null) 'JudgeCount'
    --,dbo.getjudgecount(participation_ID,2) 'JudgeEvaluationCount'
    --,dbo.GetAvgParticipationEvaluation(Participation_ID) 'Evaluation'
    --,dbo.getParticipationSpecialist(Participation_ID) as 'specialist'
from [Participation] p
    left join [Participation_Field_List] as [Actual_Field_ID] on [Actual_Field_ID].[Field_ID]= p.[Actual_Field_ID]
    left join [Participation_Result] as [Result_ID] on [Result_ID].[Result_ID]= p.[Result_ID]
OUTER APPLY (
             SELECT COUNT(CASE WHEN Sys_Is_Active=1 and status_ID = 2 THEN 1 END) AS JudgeCount,
                    AVG(CASE WHEN Sys_Is_Active=1 THEN Evaluation END) AS Evaluation,
                    COUNT(CASE WHEN Sys_Is_Active=1 THEN 1 END) AS JudgeEvaluationCount      
             FROM Judge_Participation 
             WHERE Participation_ID = p.participation_ID and (Sys_Is_Active=1 OR status_ID =2)
             ) Eval
where p.Sys_Is_Active=1 and p.is_submitted=1
于 2013-03-20T08:37:05.630 に答える
0

このクエリで関数を使用することによるパフォーマンスコストを考えました。クエリでユーザー定義関数を呼び出すと、パフォーマンスが低下します。

したがって、機能を回避する別の方法を試してみてください。

そして、表の索引を確認してください。

次のリンクを参照してください

http://www.mindfiresolutions.com/SqlServer-Query-Optimization-Tips-470.php

http://www.mssqltips.com/sql-server-tip-category/37/query-optimization/

http://blog.sqlauthority.com/2010/02/16/sql-server-stored-procedure-optimization-tips-best-practices/

于 2013-03-20T09:25:16.037 に答える
0

さて、あなたの関数には、外側の適用で使用するかなりのロジックがあることがわかります。この機能なしでテストしましたか?もちろん、ロジックが不足していますが、関数またはクエリの残りの部分が問題であるかどうかを特定するには、可能性があります。

関数の使用は、本当に必要でない限り、私はしないようにしています。私が見ることができるように、すべてのロジックをストアド プロシージャに入れることができます。

このクエリが生成するクエリ プランを調べます。その方法がわからない場合は、http://plixa.nl/how-to-read-query-execution-plans/で方法を見つけることができます。

于 2013-03-20T07:56:12.153 に答える