sql-server - SQL 服务器 2008 : Very slow query performance when dealing with specific date boundary

标签 sql-server entity-framework sql-server-2008

没错,这很奇怪。

我们有一个将数据返回给 silverlight 客户端的网络服务。使用 Entity Framework 针对 SQL Server 2008 数据库生成查询。大多数这些查询都是基于日期范围的——例如,在这个日期和那个日期之间提取结果。此外, View 用于使事情变得更容易一些。

我们注意到,当发出一组在特定日期或之后开始的特定查询时,执行速度会非常慢。这个日期是每年的 11 月 5 日。如果我们的开始日期早一天,执行将是即时的。所以,第 5 到第 6,慢。第 4 - 6 - 快。

这是 EF 生成的 SQL:

这个查询会非常慢(30 秒)

SELECT 
1 AS [C1], 
[GroupBy1].[K1] AS [Name], 
[GroupBy1].[A1] AS [C2]
FROM ( SELECT 
[Extent1].[Name] AS [K1], 
SUM([Extent1].[Value]) AS [A1]
FROM (SELECT 
  [view_answers].[Value] AS [Value], 
  [view_answers].[Comment] AS [Comment], 
  [view_answers].[NewStockist] AS [NewStockist], 
  [view_answers].[NewDistPoint] AS [NewDistPoint], 
  [view_answers].[VoucherUsed] AS [VoucherUsed], 
  [view_answers].[CashTotal] AS [CashTotal], 
  [view_answers].[AnswerType] AS [AnswerType], 
  [view_answers].[StartTime] AS [StartTime], 
  [view_answers].[ActualEndTime] AS [ActualEndTime], 
  [view_answers].[Complete] AS [Complete], 
  [view_answers].[UserID] AS [UserID], 
  [view_answers].[UserName] AS [UserName], 
  [view_answers].[QuestionType] AS [QuestionType], 
  [view_answers].[ProductSKU] AS [ProductSKU], 
  [view_answers].[BrandID] AS [BrandID], 
  [view_answers].[TeamID] AS [TeamID], 
  [view_answers].[Name] AS [Name], 
  [view_answers].[Stage] AS [Stage], 
  [view_answers].[Question] AS [Question]
  FROM [dbo].[view_answers] AS [view_answers]) AS [Extent1]
  WHERE 
     ([Extent1].[UserID] = '16E3692F-806E-40A0-BB99-ABBBCC13060D') 
     AND (N'Distribution Points' = [Extent1].[QuestionType]) 
     AND ([Extent1].[StartTime] >= '11/05/2009 00:00:00') 
     AND ([Extent1].[StartTime] <= '11/08/2009 00:00:00') 
     AND (1 = [Extent1].[Complete]) 
     AND (2 = [Extent1].[BrandID]) 
     AND (N'Distribution Points' = [Extent1].[QuestionType])
  GROUP BY 
     [Extent1].[Name])  
  AS [GroupBy1]

这个会快得多

    SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [Name], 
    [GroupBy1].[A1] AS [C2]
    FROM ( SELECT 
    [Extent1].[Name] AS [K1], 
    SUM([Extent1].[Value]) AS [A1]
    FROM (SELECT 
      [view_answers].[Value] AS [Value], 
      [view_answers].[Comment] AS [Comment], 
      [view_answers].[NewStockist] AS [NewStockist], 
      [view_answers].[NewDistPoint] AS [NewDistPoint], 
      [view_answers].[VoucherUsed] AS [VoucherUsed], 
      [view_answers].[CashTotal] AS [CashTotal], 
      [view_answers].[AnswerType] AS [AnswerType], 
      [view_answers].[StartTime] AS [StartTime], 
      [view_answers].[ActualEndTime] AS [ActualEndTime], 
      [view_answers].[Complete] AS [Complete], 
      [view_answers].[UserID] AS [UserID], 
      [view_answers].[UserName] AS [UserName], 
      [view_answers].[QuestionType] AS [QuestionType], 
      [view_answers].[ProductSKU] AS [ProductSKU], 
      [view_answers].[BrandID] AS [BrandID], 
      [view_answers].[TeamID] AS [TeamID], 
      [view_answers].[Name] AS [Name], 
      [view_answers].[Stage] AS [Stage], 
      [view_answers].[Question] AS [Question]
      FROM [dbo].[view_answers] AS [view_answers]) AS [Extent1]
    WHERE 
       ([Extent1].[UserID] = '16E3692F-806E-40A0-BB99-ABBBCC13060D') 
       AND (N'Distribution Points' = [Extent1].[QuestionType]) 
       AND ([Extent1].[StartTime] >= '11/04/2009 00:00:00') 
       AND ([Extent1].[StartTime] <= '11/08/2009 00:00:00') 
       AND (1 = [Extent1].[Complete]) 
       AND (2 = [Extent1].[BrandID]) 
       AND (N'Distribution Points' = [Extent1].[QuestionType])
    GROUP BY 
       [Extent1].[Name])  
    AS [GroupBy1]

如果我们将开始日期设置为去年 11 月 5 日,执行会很慢,去年 11 月 4 日,然后又很快。查看数据库中的数据,5号左右没有异常。此外,开始日期在 5 号之后的查询似乎运行缓慢。

我被难住了!

(数据库是远程托管的,所以我不能直接访问它)

更新

谢谢大家的回复。首先,我可能应该明确表示我对 sql server 的了解很肤浅。我构建了不同质量等级的数据库,然后使用 Linq To SQL 或 EF 之类的工具来处理它们。所以我在这里感觉有点力不从心。

关于连接——我正在查询的 View 确实包含来自大约 6-7 个表的数据。下次工作时,我将尝试获取一些统计数据,并在此处添加更多信息。我不太了解执行计划,或者它们是我可以通过 SQL Server Management Studio 看到的东西

更新 来自慢查询的统计 (3 行受影响)

Table 'tblProducts'. Scan count 0, logical reads 22, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblQuestionTypes'. Scan count 0, logical reads 1496, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblQuestions'. Scan count 0, logical reads 1496, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblSessions'. Scan count 0, logical reads 28551, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblAnswers'. Scan count 1, logical reads 1976256, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblCalls'. Scan count 1, logical reads 439, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblUsers'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

快速查询统计

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblAnswers'. Scan count 1, logical reads 7008, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblProducts'. Scan count 0, logical reads 22, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblQuestions'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblQuestionTypes'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblCalls'. Scan count 1, logical reads 439, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblSessions'. Scan count 1, logical reads 47, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblUsers'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

更新 查询执行计划(对我来说是新事物)建议我向其中一个表中的行添加一个新索引 - answers 表中的 questionid。建议的sql如下:

USE [brandfourcoke]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[tblAnswers] ([QuestionID])
INCLUDE ([CallID],[Value])
GO

查询成本的估计改进为 93%。 我应该继续这样做吗?该数据库处于实时环境中,并使用 sql server 2008 的更改跟踪和同步框架。因此,我一直担心数据库更改会影响跟踪数据并破坏我的客户。添加索引重置会更改跟踪数据吗? 谢谢大家的帮助。我觉得自己在这里完全是个初学者。

最佳答案

使用 SET sTATISTICS IO ON 运行慢速和快速查询,看看两者之间的逻辑读取/物理读取量是否存在显着差异。

数据很可能存在严重偏差。例如,快速计划执行由 10 行结果驱动的嵌套循环(导致 10 次嵌套查找),而慢速计划突然看到 10000 行,而前一个计划看到 10 行,导致 10000 次查找。尽管您的查询没有连接,但引擎可能会使用各种访问索引并将索引与集群索引连接起来。实际的执行计划总是会准确地揭示正在发生的事情。

关于sql-server - SQL 服务器 2008 : Very slow query performance when dealing with specific date boundary,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1743679/

相关文章:

sql-server - 加速恢复数据库

c# - LINQ:如何使用 IQueryable() 选择特定列

sql-server - Sqlcmd:错误:Microsoft SQL Server Native Client 10.0:通信链接失败

sql - 如何将 X% 的行更新为 A、Y% 的行更新为 B、Z% 的行更新为 C

sql-server - 如何在 Angular 6 中使用 Sql 服务器连接?

entity-framework - 生成动态选择 lambda 表达式

c# - 嵌套 MySQL 查询的解决方法?

c# - Entity Framework 代码优先 : Custom Mapping

sql - 在 sql server 中将列类型从 bigint 更改为 numeric(18,0)

SQL Server 2012 列标识增量在第 7 个条目上从 6 跳到 1000+