Microsoft SQL Server:错误的查询执行计划耗时过长
Posted
技术标签:
【中文标题】Microsoft SQL Server:错误的查询执行计划耗时过长【英文标题】:Microsoft SQL Server: wrong query execution plan taking too long 【发布时间】:2017-04-07 01:15:45 【问题描述】:这是在 Windows SQL Server 集群上。
查询来自第 3 方应用程序,因此我无法永久修改查询。
查询是:
DECLARE @FromBrCode INT = 1001
DECLARE @ToBrCode INT = 1637
DECLARE @Cdate DATE = '31-mar-2017'
SELECT
a.PrdCd, a.Name, SUM(b.Balance4) as Balance
FROM
D009021 a, D010014 b
WHERE
a.PrdCd = LTRIM(RTRIM(SUBSTRING(b.PrdAcctId, 1, 8)))
AND substring(b.PrdAcctId, 9, 24) = '000000000000000000000000'
AND a.LBrCode = b.LBrCode
AND a.LBrCode BETWEEN @FromBrCode AND @ToBrCode
AND b.CblDate = (SELECT MAX(c.CblDate)
FROM D010014 c
WHERE c.PrdAcctId = b.PrdAcctId
AND c.LBrCode = b.LBrCode
AND c.CblDate <= @Cdate)
GROUP BY
a.PrdCd, a.Name
HAVING
SUM(b.Balance4) <> 0
ORDER BY
a.PrdCd
此特定查询花费了太多时间来完成执行。同样的问题发生在不同的 SQL Server 上。
查询运行时未找到表锁,处理器和内存使用正常。
正常的“选择前 1000 个”工作并在两个表中立即显示输出(D009021、D010014)
重新索引和重建/更新两个表中的统计信息,但问题没有解决(D009021、D010014)
如果我们减少分支数量但缓慢,则相同的查询会起作用
(
DECLARE @FromBrCode INT =1001
DECLARE @ToBrCode INT =1001
)
如果我们替换任何一个变量并直接使用该值,相同的查询会在 2 分钟内更快地给出输出
AND a.LBrCode BETWEEN @FromBrCode AND @ToBrCode
改为
AND a.LBrCode BETWEEN 1001 AND @ToBrCode
如果我们在末尾添加“OPTION (RECOMPILE)”,相同的查询会运行得更快并在 2 分钟内给出输出
我尝试清理缓存查询执行计划并优化新的但问题仍然存在
发现查询估计计划和实际执行计划不一样(见截图)
【问题讨论】:
你为什么不把OPTION (RECOMPILE)
永久化?对于可能会看到具有广泛不同选择性的参数值的查询,这并没有错。
另外,您上次重建统计数据是什么时候?或者这就是您所说的第 5 步中的“重建”?
该查询来自另一个我无法修改的应用程序。重建/更新统计信息并没有解决问题
会不会是参数嗅探问题?看到这个问题。 ***.com/questions/30061405/parameter-sniffing
告诉销售该软件的第三方:Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 proper i> ANSI-92 SQL 标准(25 年前 前)中的 ANSI JOIN
语法,不鼓励使用
【参考方案1】:
表 D010014 有两次别名,一次为 b,一次为 c 它们连接到同一张表。 尝试删除下面的子查询并创建一个临时表来存储 您需要的值。我在您自己加入的字段中添加了 *
选择最大值(c.CblDate) 从 D010014 c WHERE c.PrdAcctId = b.PrdAcctId AND c.LBrCode = b.LBrCode AND c.CblDate
如果你做不到,那就试试
SELECT TOP 1 c.CblDate
FROM D010014 c
WHERE c.PrdAcctId = b.PrdAcctId
AND c.LBrCode = b.LBrCode
AND c.CblDate <= @Cdate
ORDER BY c.CblDate DESC
【讨论】:
谢谢,但正如我之前所说的“查询来自第 3 方应用程序,因此我无法永久修改查询。” 是否允许对表上的索引进行分区,或者创建新索引?如果不使用 KEEP PLAN 或 KEEPFIXED PLAN 之类的提示,至少可能会更接近估计和实际计划。以上是关于Microsoft SQL Server:错误的查询执行计划耗时过长的主要内容,如果未能解决你的问题,请参考以下文章
PCB MS SQL SERVER 字段含小写字母更新为大写字母
Microsoft SQL Server,错误: 18456
连接失败: SQLState:'01000' SQL Server 错误: 53 [Microsoft][ODBC SQL Server Driver][DBNETLIB]Connec
sql2000安装失败,错误提示([Microsoft][ODBC SQL Server Driver][Shared Memory]SQL Server 不存在或?)