Sql server 2008 观看时表现不佳

Sql server 2008 观看时表现不佳,sql-server-2008,Sql Server 2008,总体挑战: 我们每天多次为一些“市场”向表中添加项目 所以 在12:00,我们为市场“x”添加了2000个项目 12:30,我们为市场“y”添加了3000项 14:00,我们再次为市场“x”添加2500个项目 这是每天做几次 在任何时候,我们都需要每天为每个市场提取最新的商品 上述插入的预期结果为 市场“x”的2500件商品 市场“y”的3000个项目 每添加一批数据都有一个ExecutionTime时间戳,它唯一地定义了该批数据。因此,12:00时市场“x”的2000个项目将具有相同的执行

总体挑战:

我们每天多次为一些“市场”向表中添加项目

所以

  • 在12:00,我们为市场“x”添加了2000个项目
  • 12:30,我们为市场“y”添加了3000项
  • 14:00,我们再次为市场“x”添加2500个项目
这是每天做几次

在任何时候,我们都需要每天为每个市场提取最新的商品

上述插入的预期结果为

市场“x”的2500件商品

市场“y”的3000个项目

每添加一批数据都有一个ExecutionTime时间戳,它唯一地定义了该批数据。因此,12:00时市场“x”的2000个项目将具有相同的执行时间值,14:00时市场“x”的2500个项目将具有另一个执行时间值

我们已经创建了一个视图,作为

SELECT     
    *
FROM         
    dbo.Items AS s
WHERE     
    (ExecutionTime =
       (SELECT     MAX(ExecutionTime) AS Expr1
        FROM          dbo.Items AS s2
        WHERE      (SiteAlias = s.SiteAlias) AND (Market = s.Market) 
          AND (LocalTimestamp >= 
            DATEADD(dd, DATEDIFF(dd, 0, s.LocalTimestamp), 0)) 
          AND 
              (LocalTimestamp < 
            DATEADD(dd, DATEDIFF(dd, 0, s.LocalTimestamp), 1))))
我们已经在字段“执行时间”的表项上定义了索引,并在sitealias、marked和localtimestamp上定义了组合索引

问题:表演糟透了。查询大约150000行需要几分钟

我们应该对视图进行哪些明显的改进?我准备提供查询平面图等,以防我们在创建视图时没有发生简单的错误

有趣的是,如果我们在SiteAlias上用“LIKE”而不是“=”来查询视图,它将以大约90%的速度加快执行速度,这是我没有预料到的

谢谢

:o)

/小丑 哥本哈根

有趣的是,如果我们在SiteAlias上用“LIKE”而不是“=”来查询视图,它将以大约 90%——这是我没想到的

嗯,真奇怪。这可能是潜在问题的后果

查询是否持续缓慢,或者性能问题是否在一段时间后开始。 您能否在查询的末尾添加选项(重新编译),以便我们排除“参数嗅探”

您是说该表一天添加几次。SQL Server通常在使统计信息保持最新方面做得很好,但也可能是优化器使用了错误的/数据不足的统计信息

  • 此数据库的自动创建统计信息是否设置为on
  • 您能否隔离一个执行缓慢的查询实例,并在刷新所有统计信息后让它运行
最好能看到类似的执行计划和查询的=版本

更新1

您提供了估计执行计划的屏幕截图。我们需要看到实际情况(包括估计)。 另外,屏幕截图的第二个链接也不起作用

您是否可以使用xml计划更新问题,而不是将其放入注释中。这也将更有助于新人们了解这个问题

我不明白“=”版本的执行计划说,当估计的行数为1时,100%将进入键查找。那没有道理

实际执行的xml计划肯定会有所帮助。您可以查看实际行数和估计行数之间的差异,因为基数可能已关闭。 在这种情况下使用临时表可能会有所帮助,因为统计数据是准确的,您可以在其上放置索引

SELECT *
into #tempExportedData
FROM [ExportedData]

SELECT *
FROM #tempExportedData
WHERE 
  SiteAlias = 'MyAlias'
  AND LocalTimeStamp between '2012-05-14 00:00' AND '2012-05-18 00:00'
ORDER BY [Timestamp]

乍一看,您的T-SQL和表结构对我来说很好-因此这只是一个大胆的尝试:-)

在您的位置上,我可能会尝试使用CTE(公共表表达式)并将
LocalTimestamp
转换为数据类型
DATE
,因为您使用的是SQL Server 2008

有了这些,您的观点可以是:

CREATE VIEW dbo.YourView
AS
   WITH DataPerDay AS
   (
      SELECT 
         *,
         RowNum = ROW_NUMBER() OVER (PARTITION BY CAST(LocalTimestamp AS DATE) 
                                     ORDER BY ExecutionTime DESC)
      FROM         
         dbo.Items AS s
   )
   SELECT *
   FROM DataPerDay 
   WHERE RowNum = 1
基本上,CTE按照
LocalTimestamp
中仅日期的部分对数据进行“分区”,然后从1开始为当天的所有条目分配序列号,因此每天的“最新”或“最新”条目得到
RowNum=1
,这是我在从该CTE中选择时使用的


这绕过了
SELECT(MAX)…
子查询,在我个人的观察中似乎快了一点-但这在很大程度上取决于您的表和数据-所以您自己试试看,看看是否有帮助

您在基础表
Items
上有什么类型的索引?视图查询的执行计划会有所帮助。@marc\s基础表上定义的索引是字段执行时间上的非聚集索引字段上的组合非聚集索引sitealias,marked和localtimestamp。似乎很合理-您是否查看了针对视图的某个查询的执行计划?我从您的评论中了解到,您在sitealias、marked和localtimestamp字段上有一个组合的非聚集索引。您知道指定列的顺序很重要,对吗?只有当LoalTimeType是优化器将考虑使用的第一列时,就可以在这里找到相等的执行计划(它的可视化表示):(因此,您需要它的XML版本吗?)“LIKE”的执行计划可以在这里看到:我添加了选项(重新编译),但它并没有产生任何影响。尽管如此,在数据库上设置了自动创建统计信息。我曾尝试在使用sp_updatestats更新statics后运行查询,但没有结果effect@JesperLundStocholm在2008年运行时,
SELECT*FROM master..spt_值,其中name='rpc'
SELECT*FROM master..spt_值,其中name像'rpc'
给出了
1
vs
18.563
的估计行数,因此它似乎使用了一种不同的计算基数估计值的方法可能是因为某种原因,这可能是你得到不同计划的原因。2005年的数字是
1
vs
1.84724
@Jesper你有什么进展吗?我用一些新的建议更新了我的答案。此外,如果可以远程桌面,它可以增加快速解决方案的机会,但我想这是不可能的。这很有趣,我会尝试一下。我用了你的
SELECT *
into #tempExportedData
FROM [ExportedData]

SELECT *
FROM #tempExportedData
WHERE 
  SiteAlias = 'MyAlias'
  AND LocalTimeStamp between '2012-05-14 00:00' AND '2012-05-18 00:00'
ORDER BY [Timestamp]
CREATE VIEW dbo.YourView
AS
   WITH DataPerDay AS
   (
      SELECT 
         *,
         RowNum = ROW_NUMBER() OVER (PARTITION BY CAST(LocalTimestamp AS DATE) 
                                     ORDER BY ExecutionTime DESC)
      FROM         
         dbo.Items AS s
   )
   SELECT *
   FROM DataPerDay 
   WHERE RowNum = 1