web-dev-qa-db-ja.com

クエリプランのメモリ "過剰な許可"に関する警告-何が原因であるかを見つける方法は?

メモリExcessive Grantに関する警告を表示するクエリを実行しています。

複雑なviewを含め、使用されているテーブルとインデックスが多すぎるため、ここですべての定義を追加することは困難です。

Excessive Grantの原因を突き止めようとしています。コンバージョンになるのでしょうか?

実行プランを見ると、次のことがわかります。

<ScalarOperator
  ScalarString="CONVERT(date,[apia_repl_sub].[dbo].[repl_Aupair].[ArrivalDate] as [repl].[ArrivalDate],0)">
  <Convert DataType="date" Style="0" Implicit="false">
    <ScalarOperator>
      <Identifier>
        <ColumnReference Database="[apia_repl_sub]" Schema="[dbo]" Table="[repl_Aupair]" Alias="[repl]" Column="ArrivalDate" />
      </Identifier>
    </ScalarOperator>
  </Convert>
</ScalarOperator>

そしてこれは:

<ScalarOperator ScalarString="CONVERT(date,[JUNOCORE].[dbo].[applicationPlacementInfo].[arrivalDate] as [pi].[arrivalDate],0)">
  <Convert DataType="date" Style="0" Implicit="false">
    <ScalarOperator>
      <Identifier>
        <ColumnReference Database="[JUNOCORE]" Schema="[dbo]" Table="[applicationPlacementInfo]" Alias="[pi]" Column="arrivalDate" />
      </Identifier>
    </ScalarOperator>
  </Convert>
</ScalarOperator>

これがクエリです 実行プランを含むクエリもここに表示されます

DECLARE @arrivalDate DATEtime = '2018-08-20'

SELECT      app.applicantID,
            app.applicationID,
            a.preferredName,
            u.firstname,
            u.lastname,
            u.loginId                       AS emailAddress,
            s.status                        AS statusDescription,
            CAST(repl.arrivalDate AS DATE)  AS arrivalDate,
            app.moodleCourseComplete,
            app.moodleCourseCompleteUpdated,
            u.loginId,
            c.countryName
FROM        app.application                  AS app
JOIN        app.applicant                    AS a    ON a.applicantId = app.applicantId
JOIN        usr.[user]                       AS u    ON u.userId = a.userId
JOIN        app.ref_applicationStatus        AS s    ON s.statusCode = app.status
JOIN        APIA_Repl_Sub.dbo.repl_Aupair    AS repl ON repl.JunoCore_applicationID = app.applicationID

JOIN        app.Country                      AS c    ON c.countryCode = a.nationalityCode
WHERE       repl.arrivalDate = @arrivalDate

UNION ALL

(
    SELECT      app.applicantID,
                app.applicationID,
                app.preferredName,
                app.firstname,
                app.lastname,
                app.emailAddress,
                ap.status,
                CAST(app.arrivalDate AS DATE)    AS arrivalDate,
                app.moodleCourseComplete,
                app.moodleCourseCompleteUpdated,
                app.emailAddress                 AS loginId,
                c.countryName
    FROM        JUNOCore.dbo.vw_SelectApplication    AS app
                INNER JOIN JUNOCore.dbo.country c ON c.countryCode = app.nationalityCode
                INNER JOIN JUNOCore.dbo.application as ap ON ap.applicationID = app.applicationID
    WHERE        arrivalDate    = @arrivalDate AND
                app.applicationID NOT IN (SELECT p4.applicationId FROM APCore.app.application p4)
)

警告は次のようになります。

Enter image description here

実行計画はこちら

この警告にどのように対処しますか?

前に言ったように、コンバージョンを調べていました。この過剰な許可の考えられる原因を示す、実行計画で探すことができるものはありますか?

Obs。関連するオブジェクトが多すぎると言いましたが、この問題に対処するのに役立つ場合は、リクエストに応じて必要なものをここに追加できます。問題ない。

9

メモリを消費する最も一般的な2つのタイプの演算子は次のとおりです。

  • 並べ替え
  • ハッシュ

プランが並列の場合、メモリ要件は、スレッドが行を渡すための交換を補うためにいくらか増加します。パラレルプランでは、シリアルメモリ全体の許可* DOPは必要ありません(ただし、シリアルで必要なメモリとDOPの間に関係がある場合があります)。完全な付与は分割され、(うまくいけば)プラン内のすべてのスレッドで均等に使用されます。

場合によっては、 Nested Loops Join もメモリを要求することがあります。

メモリーの付与は、行数と、メモリーを消費するオペレーターを通過するデータのサイズに基づいて、オプティマイザーによって計算されます。上記のように、計画が並行している場合は、さらに要求される場合があります。別の要因は、メモリを消費するオペレーターがメモリを共有できることです。

たとえば、並べ替えによって消費されるメモリの一部は、データの並べ替え後に上流のオペレーターに渡すことができます。また、最初のビルドフェーズが完了し、プローブされた行が上流に移動し始めた後、ハッシュが上流のメモリを渡すことがあります。これは、メモリフラクション情報を介して確認できます。

計画には、3つのソート演算子があります。

NUTS

これらを組み合わせると、オプティマイザは、ディスクに影響を与えずに実行するには2 MBのメモリが必要になると考えています。 24 KBしか必要としないため、警告が表示されます。

メモリ許可の誤った見積もりは、多くの場所から発生する可能性があります。クエリには、単一の変数があります:@arrivalDate

このパラメーターがストアドプロシージャ内にあるのか、ローカルで呼び出すのかは明確ではありません。どちらの場合でも、再コンパイルのヒントを試して、異なるカーディナリティの見積もりを取得することで警告が削除されるかどうかを確認できます。

それがうまくいかない場合は、個別のソート操作が不要になるようにインデックスを調整してみることをお勧めしますが、そのような少量のメモリの場合よりも複雑になる可能性があります。

参考のために:

11
Erik Darling