Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Microsoft SQL Server:错误的查询执行计划花费的时间太长_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql server Microsoft SQL Server:错误的查询执行计划花费的时间太长

Sql server Microsoft SQL Server:错误的查询执行计划花费的时间太长,sql-server,sql-server-2008,Sql Server,Sql Server 2008,这在Windows SQL Server群集上 查询来自第三方应用程序,因此我无法永久修改查询 查询是: 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.

这在Windows SQL Server群集上

查询来自第三方应用程序,因此我无法永久修改查询

查询是:

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
如果我们替换任何一个变量并直接使用该值,那么同样的查询在2分钟内给出输出的速度会更快

 AND a.LBrCode BETWEEN @FromBrCode AND @ToBrCode
改为

AND a.LBrCode BETWEEN 1001 AND @ToBrCode
如果我们在末尾添加“OPTION(RECOMPILE)”,同样的查询工作得更快,并在2分钟内给出输出

我试图清理缓存查询执行计划并优化新计划,但问题仍然存在

发现查询估计计划和实际执行计划不同(请参见屏幕截图)


表D010014有两个别名,一个是b,一个是c 它们被联接到同一个表。 尝试删除下面的子查询并创建一个临时表来存储 你需要的价值观。我将*添加到您自行加入的字段中

选择最大值(c.CblDate) 从D010014 c开始 其中c.PrdAcctId=b.PrdAcctId c.LBrCode=b.LBrCode
还有c.CblDate为什么不把
选项(重新编译)
永久化呢?对于可能看到选择性差异很大的参数值的查询来说,这没有什么错。另外,上次重建统计数据是什么时候?或者这就是你在第5步中所说的“重建”吗?这个查询来自另一个应用程序,我无法修改它。重建/更新统计数据没有解决问题这可能是参数嗅探问题吗?看这个问题。告诉您销售该软件的第三方:-在ANSI-92 SQL标准(25年前)中,旧式逗号分隔的表列表样式已被正确的ANSI
JOIN
语法所取代,因此不鼓励使用它。谢谢,但正如我前面所说,“查询来自第三方应用程序,因此我无法永久修改查询。”是否允许对表上的索引进行分区,或创建新索引?如果不使用“保持计划”或“保持固定计划”之类的提示,至少可以更接近估计和实际计划。
AND a.LBrCode BETWEEN 1001 AND @ToBrCode
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