J'exécute une requête qui donne l'avertissement d'une mémoire Excessive Grant
.
Il y a trop de tables et d'index utilisés, y compris un view
complexe, et il est donc difficile d'ajouter toutes les définitions ici.
J'essaie de trouver ce qui pourrait me causer le Excessive Grant
. Peut-il s'agir de conversions?
En regardant le plan d'exécution, je peux voir ce qui suit:
<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>
Et celui-là:
<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>
Voici la requête, bien que vous puissiez voir la requête avec le plan d'exécution ici aussi :
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)
)
Voici à quoi ressemble l'avertissement:
Comment puis-je faire face à cet avertissement?
Comme je l'ai dit auparavant, je regardais les conversions. Y a-t-il quelque chose que je puisse rechercher dans le plan d'exécution qui indiquerait les causes possibles de cette subvention excessive?
Obs. J'ai dit qu'il y avait trop d'objets impliqués, cependant, je peux ajouter ici tout ce qui est requis sur demande si cela peut aider à résoudre ce problème. Aucun problème.
Les deux types d'opérateurs les plus courants qui consomment de la mémoire sont:
Si un plan est parallèle, les besoins en mémoire augmenteront pour compenser les échanges de threads à traverser les lignes. Les plans parallèles ne nécessitent pas l'intégralité de l'allocation de mémoire série * DOP (bien qu'il puisse exister une relation entre la mémoire série requise et DOP). La subvention complète est divisée et (espérons-le) utilisée uniformément sur tous les threads du plan.
Dans certains cas, Nested Loops Join peut également demander de la mémoire.
Les allocations de mémoire sont calculées par l'optimiseur en fonction du nombre de lignes et de la taille des données qui passeront par les opérateurs consommant de la mémoire. Comme ci-dessus, si le plan est parallèle, il peut demander plus. Un autre facteur est que les opérateurs consommateurs de mémoire peuvent partager la mémoire.
Par exemple, une partie de la mémoire consommée par un tri peut être transmise aux opérateurs en amont après le tri des données, et les hachages peuvent passer la mémoire en amont une fois la phase de construction initiale terminée, et les lignes sondées commencent à se déplacer en amont. Cela peut être observé via les informations sur les fractions de mémoire.
Dans votre plan, vous avez trois opérateurs de tri.
Ce qui, combiné, l'optimiseur pense qu'il aura besoin de 2 Mo de mémoire pour fonctionner sans se répandre sur le disque. Il ne nécessite finalement que 24 Ko, d'où l'avertissement.
Les erreurs d'estimation des allocations de mémoire peuvent provenir de nombreux endroits. Dans votre requête, vous avez une seule variable: @arrivalDate
.
Il n'est pas clair si ce paramètre se trouve dans une procédure stockée, ou si vous l'appelez localement. Dans les deux cas, vous pouvez essayer une astuce de recompilation pour voir si cela supprime l'avertissement en obtenant une estimation de cardinalité différente.
Si cela ne fonctionne pas, vous pouvez essayer d'ajuster les index afin que des opérations de tri distinctes ne soient pas nécessaires, mais cela peut être plus compliqué que cela ne vaut pour une si petite quantité de mémoire.
Pour référence:
Dépannage des problèmes de reniflage de paramètres de la bonne façon: partie 1 (des liens vers d'autres parties sont fournis dans le premier message)