Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/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查询超时,具体取决于Where子句_Sql_Sql Server_Sql Server 2008r2 Express - Fatal编程技术网

SQL Server查询超时,具体取决于Where子句

SQL Server查询超时,具体取决于Where子句,sql,sql-server,sql-server-2008r2-express,Sql,Sql Server,Sql Server 2008r2 Express,我有一个查询,它使用了3个函数和下面的几个不同视图,这些太复杂了,无法在这里发布。我遇到的一件奇怪的事情是,在运行顶级查询时,有多个搜索键会导致查询运行大约需要一个小时,而将查询一分为二每次查询大约需要5秒 以下是顶级查询: Select * from dbo.vwSimpleInvoice i inner join dbo.vwRPTInvoiceLineItemDetail d on i.InvoiceID = d.InvoiceID 当我添加where条款时: Where i.I

我有一个查询,它使用了3个函数和下面的几个不同视图,这些太复杂了,无法在这里发布。我遇到的一件奇怪的事情是,在运行顶级查询时,有多个搜索键会导致查询运行大约需要一个小时,而将查询一分为二每次查询大约需要5秒

以下是顶级查询:

Select * 
from  dbo.vwSimpleInvoice i 
inner join dbo.vwRPTInvoiceLineItemDetail d on i.InvoiceID = d.InvoiceID 
当我添加where条款时:

Where i.InvoiceID = 109581
Where i.InvoiceID = 109582
查询运行大约需要3秒钟。同样,当我添加where子句时:

Where i.InvoiceID = 109581
Where i.InvoiceID = 109582
大约需要3秒钟

但当我添加此where子句时:

Where i.InvoiceID in (109581, 109582)
我不得不在大约50分钟后终止查询,但它从未返回任何结果

这发生在运行SQL server 2008 R2 Express的远程客户端服务器上。当我在本地(同样在SQLServer2008R2 Express上)运行它时,我不会得到巨大的延迟,最后一个where子句大约需要30秒才能返回。客户的数据比我多得多

知道从哪里开始解决这个问题吗

编辑:

在下面的评论之后,我重建了索引和统计信息,这提高了前两个where子句的性能,但对第三个没有影响。然后我对查询进行了处理,发现如果我将其改写为:

Select * 
from  dbo.vwSimpleInvoice i 
inner join  
    (Select * from dbo.vwRPTInvoiceLineItemDetail) d on i.InvoiceID = d.InvoiceID 
Where i.InvoiceID in (109581, 109582)
性能恢复到预期水平,大约200毫秒。我现在对正在发生的事情比以往任何时候都更加困惑

编辑2:

事实上,我错了。不是这样重写查询,我在重写过程中意外地将Where子句更改为:

Where d.InvoiceID in (109581, 109582)
(将
i
更改为
d

仍然有点不明白为什么这会在内部连接上产生如此巨大的差异


进一步编辑:

再进一步玩弄这个,我还是无法理解

Select InvoiceId from tblInvoice Where CustomerID = 2000
返回:

80442, 4988, 98497, 102483, 102484, 107958, 127063, 168444, 168531, 173382, 173487, 173633, 174013, 174160, 174240, 175389

Select * from dbo.vwRPTInvoiceLineItemDetail
Where InvoiceID in 
(80442, 4988, 98497, 102483, 102484, 107958, 127063, 168444, 168531, 173382, 173487, 173633, 174013, 174160, 174240, 175389)
运行:31行返回110毫秒

Select * from dbo.vwRPTInvoiceLineItemDetail
Where InvoiceID in 
(Select InvoiceId from tblInvoice Where CustomerID = 2000)

运行:返回31行65分钟

您遇到的问题(几乎可以肯定)是由于缓存查询计划造成的,该计划适用于传递给查询的某些版本的参数,但不适用于其他版本(aka)

这是一种常见的情况,过时的统计数据和/或严重碎片化的索引往往会使情况变得更糟

第一步:确保已重建所有索引,且非索引列的统计信息是最新的。(另外,确保您的客户有定期的索引维护工作)

这是规范参考:

如果在重建索引和更新统计信息后问题仍然存在,那么您有几个选项:

  • 使用动态SQL(但请先阅读以下内容:)

  • 使用

  • 与(重新编译)


  • 执行计划是什么样子的?您是否尝试过使用OR更改“IN”运算符?说“其中d.InvoiceID=109581或d.InvoiceID=109582”。可能会改变执行计划!但是获得帮助的真正方法是在WHERE中发布单个ID与2个ID的执行计划,这样其他人就可以分析差异并理解为什么会这样。我必须从头重写查询。我无法找出导致上述行为的任何原因。原始查询的行为仍然是这样的,我重写了整个树以避免最后的连接。谢谢您的帮助。InvoiceID在两个表上都是varchar还是INT?好的,重建所有索引和统计信息,检查单个InvoiceID的估计执行计划和实际计划,并根据建议调整一个索引。单个InvoiceID的执行时间现在降低到48毫秒左右,这是一个巨大的改进。但最后一个where子句仍在运行,直到我单击stop,当时它大约运行了20分钟。谢谢你迄今为止的帮助,有进一步的建议吗?不确定你是否得到通知,但只是在尝试了你的建议后编辑了我的问题。有什么想法吗?再次感谢。