Mar*_*lli 18 performance sql-server optimization execution-plan query-performance performance-tuning
我正在运行一个查询,该查询给出有关内存的警告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>
Run Code Online (Sandbox Code Playgroud)
和这个:
<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>
Run Code Online (Sandbox Code Playgroud)
这是查询,尽管您也可以在此处查看带有执行计划的查询:
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)
)
Run Code Online (Sandbox Code Playgroud)
这是警告的样子:
我该如何处理这个警告?
正如我之前所说,我正在研究转换。我可以在执行计划中寻找任何可以表明这种过度拨款的可能原因的东西吗?
观察。我说涉及的对象太多,但是,如果可能有助于解决此问题,我可以根据要求在此处添加所需的任何内容。没问题。
Eri*_*ing 23
最常见的两种消耗内存的运算符是:
如果计划是并行的,内存需求将增加一定数量,以补偿线程通过行的交换。并行计划不需要整个串行内存授予 * DOP(尽管串行所需内存和 DOP 之间可能存在关系)。完全授权被拆分并(希望)在计划中的所有线程中均匀使用。
在某些情况下,嵌套循环连接也可能要求内存。
内存授权由优化器根据行数和将通过内存消耗运算符的数据大小计算。如上所述,如果计划是并行的,则可能会要求更多。另一个因素是内存消耗操作符可以共享内存。
例如,排序消耗的一些内存可以在数据排序后传递给上游操作符,并且哈希可以在初始构建阶段完成后将内存传递给上游,并且被探测的行开始向上游移动。这可以通过内存分数信息观察到。
在您的计划中,您有三个 Sort 运算符。
综合起来,优化器认为它需要 2 MB 的内存才能运行而不会溢出到磁盘。它最终只需要 24 KB,因此出现警告。
内存授予错误估计可能来自很多地方。在您的查询中,您有一个变量:@arrivalDate.
不清楚此参数是否在存储过程中,或者您是否在本地调用它。在任何一种情况下,您都可以尝试重新编译提示,以查看是否通过获得不同的基数估计来消除警告。
如果这不起作用,您可能想尝试调整索引,以便不需要单独的排序操作,但这可能比如此少量的内存更值得。
以供参考:
以正确的方式对参数嗅探问题进行故障排除:第 1 部分(第一篇文章中提供了其他部分的链接)