同一SQL查询在一个数据库中运行的时间比在同一服务器下的另一个数据库中运行的时间长

同一SQL查询在一个数据库中运行的时间比在同一服务器下的另一个数据库中运行的时间长,sql,sql-server,performance,sql-server-2008,sql-execution-plan,Sql,Sql Server,Performance,Sql Server 2008,Sql Execution Plan,我有一个SQL数据库服务器,下面有两个数据库,具有相同的结构和数据。我在这两个数据库中运行相同的sql查询,其中一个需要更长的时间,而另一个完成时间不到50%。他们都有不同的执行计划 该视图的查询如下所示: SELECT DISTINCT i.SmtIssuer, i.SecID, ra.AssetNameCurrency AS AssetIdCurrency, i.IssuerCurrency, seg.ProxyCurrency, shifts.ScenarioDate, ten.Teno

我有一个SQL数据库服务器,下面有两个数据库,具有相同的结构和数据。我在这两个数据库中运行相同的sql查询,其中一个需要更长的时间,而另一个完成时间不到50%。他们都有不同的执行计划

该视图的查询如下所示:

SELECT DISTINCT  i.SmtIssuer, i.SecID, ra.AssetNameCurrency AS AssetIdCurrency, i.IssuerCurrency, seg.ProxyCurrency, shifts.ScenarioDate, ten.TenorID, ten.Tenor, 
                      shifts.Shift, shifts.BusinessDate, shifts.ScenarioNum
FROM         dbo.tblRrmIssuer AS i INNER JOIN
                      dbo.tblRrmSegment AS seg ON i.Identifier = seg.Identifier AND i.SegmentID = seg.SegmentID INNER JOIN
                      dbo.tblRrmAsset AS ra ON seg.AssetID = ra.AssetID INNER JOIN
                      dbo.tblRrmHistSimShift AS shifts ON seg.Identifier = shifts.Identifier AND i.SegmentID = shifts.SegmentID INNER JOIN
                      dbo.tblRrmTenor AS ten ON shifts.TenorID = ten.TenorID INNER JOIN
                      dbo.tblAsset AS a ON i.SmtIssuer = a.SmtIssuer INNER JOIN
                      dbo.tblRrmSource AS sc ON seg.SourceID = sc.SourceID
WHERE     (a.AssetTypeID = 0) AND (sc.SourceName = 'CsVaR') AND (shifts.SourceID =
                          (SELECT     SourceID
                            FROM          dbo.tblRrmSource
                            WHERE      (SourceName = 'CsVaR')))
我已经尝试过的是-在表上重建和重新组织索引(tblRRMHistSimShifts-此表有200多万条记录),检查服务器上的锁或其他后台进程或错误,服务器的最大并行度为0


您还有什么建议可以解决这个问题吗

最好的方法是重建和重新组织您的请求

SELECT DISTINCT  i.SmtIssuer, i.SecID, ra.AssetNameCurrency AS AssetIdCurrency, i.IssuerCurrency, seg.ProxyCurrency, shifts.ScenarioDate, ten.TenorID, ten.Tenor, 
                 shifts.Shift, shifts.BusinessDate, shifts.ScenarioNum
FROM dbo.tblRrmIssuer AS i INNER JOIN dbo.tblRrmSegment AS seg ON i.Identifier = seg.Identifier AND i.SegmentID = seg.SegmentID 
                           INNER JOIN dbo.tblRrmSource AS sc ON seg.SourceID = sc.SourceID
                           INNER JOIN dbo.tblRrmAsset AS ra ON seg.AssetID = ra.AssetID 
                           INNER JOIN dbo.tblRrmHistSimShift AS shifts ON seg.Identifier = shifts.Identifier AND i.SegmentID = shifts.SegmentID AND shifts.SourceID = sc.SourceID
                           INNER JOIN dbo.tblRrmTenor AS ten ON shifts.TenorID = ten.TenorID 
                           INNER JOIN dbo.tblAsset AS a ON i.SmtIssuer = a.SmtIssuer 
WHERE (a.AssetTypeID = 0) AND (sc.SourceName = 'CsVaR')

事实上,您在同一服务器上有两个数据库,并且具有相同的数据集(如您所说),这并不能确保相同的执行计划

以下是查询计划可能不同的一些原因:

  • mdf和ldf文件(针对每个数据库)位于不同的驱动器上。如果有 驱动器速度更快,数据库运行查询的速度也会更快
  • 统计数据停滞不前。如果您有一个数据库的统计数据比 另一方面,SQL有更好的机会选择合适的(和
    (更快)执行计划
  • 索引:我知道你说它们都是相同的,但我会检查一下 如果两个上的索引类型相同
重点是查看查询运行缓慢的原因,或者查看实际的执行计划,而不是比较。检查慢速查询的实际执行计划将提示您为什么运行较慢


另外,我不会添加NO-LOCK语句来解决这个问题。根据我的经验,大多数较慢的查询都可以通过代码或索引进行优化,而不是添加一个无锁提示,根据您的事务,该提示可能会使您修改或使用旧的结果集。

子查询可能是多余的。可以通过数据库引擎优化顾问运行它。速度越快的数据库可能有一些速度越慢的数据库所没有的统计数据和索引。请尝试在正在进行连接的表上添加(nolock)。看看它是否能提高性能。有多少数据/日志文件?它们是如何设置的?这两个数据库之间有区别吗?你能同时发布这两个数据库吗。两个数据库中的数据是否相同?我尝试删除冗余子查询并重新启动SQL服务,但没有成功。我检查了一个需要很长时间才能运行的查询计划,表上的聚集索引Seek-tblRrmHistSimShift的成本为54%,这是一个有大约200万条记录的表。如果架构和统计数据保持不变,重新启动SQL server可能不会更改执行计划,它只会清除缓存。实际上,在生产服务器上是个坏主意。正如我前面提到的,我建议您深入研究一下您的执行计划,因为您说它运行缓慢。但是如果你找到了一个索引搜索,你就没有办法让它更快了。如果可以,请尝试归档该表(移动旧记录)。对较少记录的索引搜索总是更快。