1

正常に動作している大規模なクエリがありますが、データベース内のレコードの数が原因で、ストアド プロシージャが完了するまでにクエリの時間がどんどん長くなっていきます。

そもそもクエリを機能させるのに十分な時間があり、A) クエリを単純化するか、B) より小さなクエリ/ストアド プロシージャに分割するかについて、自信がありません。

専門家は私を助けることができますか?

SELECT 
    r.resourceFirstName, 
    r.resourceLastName,
    a.eventDateTime, 
    CONVERT(char(1), a.eventType) as eventType, 
    CONVERT(varchar(5), a.reasonCode) as reasonCode, 
    r.extension, 
    GETDATE() AS ciscoDate into #temp_Agent
FROM 
    CCX1.db_cra.dbo.Resource r 
    INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a 
        ON r.resourceID = a.agentID 
    INNER JOIN ( 
        SELECT 
            p.resourceFirstName, 
            p.resourceLastName, 
            MAX(e.eventDateTime) MaxeventDateTime 
        FROM 
            CCX1.db_cra.dbo.Resource p 
            INNER JOIN CCX1.db_cra.dbo.AgentStateDetail e 
            ON p.resourceID = e.agentID 
        where 
            e.eventDateTime > (GETDATE() - 1)
        GROUP BY 
            p.resourceFirstName, 
            p.resourceLastName
    ) d 
        ON r.resourceFirstName = d.resourceFirstName 
        AND r.resourceLastName = d.resourceLastName 
        AND a.eventDateTime = d.MaxeventDateTime 
        AND r.active = 1 
where 
    a.eventDateTime >= (GETDATE() - 7)
ORDER BY 
    r.resourceLastName,
    r.resourceFirstName ASC

4

3 に答える 3

0

テーブルの完全な定義がなければ、クエリがハングアウトする理由をトラブルシューティングするのは困難ですが、クエリのパフォーマンスを向上させるのに役立つヒントをいくつか紹介します。

  1. 「#temp_Agent」などの一時テーブルを使用する代わりに、「テーブル」タイプのローカル変数を作成することをお勧めします。まったく同じ結果を達成できますが、次の理由により、パフォーマンスを大幅に向上させることができます。

    • 「テーブル」タイプのローカル変数は、主キーとインデックスを使用して作成できます。これにより、SQL が情報を検索する方法が改善されます。

    • 情報がディスクから直接アクセスされるため、ローカル変数をクラスター化することができます。これにより、特定のシナリオでのパフォーマンスも向上します。

    • 一時テーブルでは、クエリによって取得された情報を格納するために使用する必要がある列の型を SQL が実行時に解決する必要があります。

  2. 一時テーブルや変数などに情報を保存する必要がある場合は、それらの変数に不要な情報を保存しないようにします。たとえば、プロセスで 2 つの ID 列のみが必要な場合は、泡を取得できる余分な列を含めないようにします。

  3. 複数のソースから取得する必要がある情報が多数ある場合は、ビューの使用を検討する必要があります。これは、インデックスを作成して情報の取得を改善することもできます。

  4. 文字列の不要な並べ替え、グループ化、変換、および結合を使用しないでください。これらの特定の操作は、クエリのパフォーマンスを大幅に低下させます。

追加のヒントとして、データベースとオブジェクトを改善するために設計された SQL サーバー ツールを利用できます。

  • クエリの実行計画を確認します (メニュー クエリ -> 実際の実行計画を含める、またはコントロール + M)。
  • SQL Server Engine Tunning Advisor を実行してトレース ファイルを分析し (SQL Server Profiler を参照)、インデックスを追加してデータベースのパフォーマンスを向上させます。
  • 情報を取得するために使用しているテーブルでクエリがデッドロックを生成していない場合は、SQL Server プロファイラーで確認してください。すべてのクエリで「ヒント」を使用して、特定のシナリオで回避したいロックの問題やその他の動作を回避することをお勧めします。

添付のリンクを参照して、私の意味をよりよく理解してください。

実行計画について

ヒントの使用法

SQL Server で利用可能なチューニング オプション

情報がお役に立てば幸いです。

于 2013-02-01T19:33:18.393 に答える
0

これが SQLServer であると仮定して、次を試してください。

WITH CTE AS
(SELECT r.resourceFirstName, 
        r.resourceLastName,
        a.eventDateTime, 
        CONVERT(char(1), a.eventType) as eventType, 
        CONVERT(varchar(5), a.reasonCode) as reasonCode, 
        r.extension, 
        GETDATE() AS ciscoDate,
        RANK() OVER (PARTITION BY r.resourceFirstName, r.resourceLastName
                     ORDER BY a.eventDateTime DESC) RN
 FROM CCX1.db_cra.dbo.Resource r 
 INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a 
         ON r.resourceID = a.agentID AND a.eventDateTime >= (GETDATE() - 1) 
 where r.active = 1)
SELECT resourceFirstName, resourceLastName, eventDateTime, eventType, reasonCode, r.extension, ciscoDate
into #temp_Agent
FROM CTE
WHERE RN=1
ORDER BY r.resourceLastName, r.resourceFirstName ASC
于 2013-02-01T19:48:59.643 に答える
0

クエリだけでは正解は出せません。しかし...

「eventDateTime」にインデックスを付けることを検討してください。

1 日以内に一連のレコードに参加しているようです。これにより、外側のクエリの 7 日間のフィルターが無関係になります。私にはテストする能力がありませんが、クエリをこれに減らすことができますか? (以下の疑似コード)

また、さまざまなソリューションを検討してください。たぶん、日時に基づいてテーブルを分割します。スター スキーマまたはキューブ デザインを使用して、レポート用に別のデータベースを用意することもできます。

一時テーブル #temp_Agent で何が行われていますか?

declare @max datetime = (select max(eventDateTime) 
                         from CCX1.db_cra.dbo.AgentStateDetail 
                         where active=1 
                         and eventDateTime > getdate()-1);
if(@max is null)
    exit no records today

SELECT r.resourceFirstName, 
r.resourceLastName,
a.eventDateTime, 
CONVERT(char(1), a.eventType) as eventType, 
CONVERT(varchar(5), a.reasonCode) as reasonCode, 
r.extension, 
GETDATE() AS ciscoDate 

into #temp_Agent

FROM CCX1.db_cra.dbo.Resource r 
INNER JOIN CCX1.db_cra.dbo.AgentStateDetail a ON r.resourceID = a.agentID 

where r.active = 1 
and a.eventDateTime = @max;
于 2013-02-01T19:15:50.207 に答える