-1

我正在运行像 ( Select top 10 records, joins, counts, group by) 这样的简单查询来根据要求获取行和统计信息。表有大约 150,000 到 200,000 行。所有主键和外键都定义明确。

但是我在运行查询时随机收到超时错误。相同的查询或存储过程需要不同的时间来完成。数据库托管在共享服务器上。我将命令超时属性设置为 600,但它不起作用。我的服务提供商说如果处理未完成,系统将在 30 秒后终止查询。他们告诉我调整查询以匹配时间。

例如。

CREATE PROCEDURE [dbo].[NP_TableReport]  
(    
 @CreatedOnFrom datetime = NULL,  
 @CreatedOnTo datetime = NULL
)    
AS    
BEGIN  

 SELECT COUNT(ID) [Count]    
 FROM Table1
 WHERE     
     (@CreatedOnFrom IS NULL OR @CreatedOnFrom <= CreatedOn)  
 AND (@CreatedOnTo IS NULL OR @CreatedOnTo >= CreatedOn)  
END 

请告诉我是什么导致了随机超时错误?当我在专用服务器上尝试相同的操作时,错误消失了。有人可以解释发生了什么吗?

4

3 回答 3

4

Table1首先在CreateOn字段上添加索引。

使用count(*)而不是count(id),除非您特别想计算列中的非空值id

根据您的输入值,您有四个不同的查询,因此对它们进行专门化可能会有所帮助:

if (@CreatedOnFrom is null and @CreatedOnTo is null) begin

  select count(*) [count]
  from Table1

end else if (@CreatedOnFrom is null) begin

  select count(*) [count]
  from Table1
  where @CreatedOnTo >= CreatedOn

end else if (@CreatedOnTo is null) begin

  select count(*) [count]
  from Table1
  where @CreatedOnFrom <= CreatedOn

end else begin

  select count(*) [count]
  from Table1
  where @CreatedOnTo >= CreatedOn and @CreatedOnFrom <= CreatedOn

end
于 2013-04-19T12:57:41.780 回答
0

如果可以事先完成,我想我不会在查询中进行太多计算。带有空值的不等式通常非常严重,IMX。

CREATE PROCEDURE [dbo].[NP_TableReport]  
(    
 @CreatedOnFrom datetime = NULL,  
 @CreatedOnTo datetime = NULL
)    
AS    
BEGIN  

 SET @CreatedOnFrom = COALESCE(@CreatedOnFrom, CAST('01/01/1753' as datetime))
 SET @CreatedOnTo = COALESCE(@CreatedOnTo, CAST('12/31/9999' as datetime))

 SELECT COUNT(ID) [Count]    
 FROM dbo.Table1
 WHERE CreatedOn BETWEEN @CreatedOnTo AND @CreatedOnFrom

END 

请注意,如果Table1.CreatedOn包含午夜之后的时间组件,但您只想向过程提交日期,则可能需要使用它来代替:

 SET @CreatedOnTo = COALESCE(DATEADD(day,1,@CreatedOnTo), CAST('12/31/9999 23:59:59' as datetime))

您甚至可以从中减去一秒以获得DATEADD指定日期的最后一秒。

您可以将COALESCE语句放入WHERE子句中,但我发现这更容易阅读。

于 2013-04-19T15:16:14.177 回答
0

对于超过 200K 的元组,平均查询可能很容易需要 30 秒以上才能完成。如果您的托管服务提供商不允许查询时间超过 30 秒,请考虑使用客户端技术获取和过滤数据。如果即使这样也不起作用,那么请考虑更改您的托管服务提供商或为您的应用程序购买单独的数据库托管服务。

您已经提到您已经在“createdOn”列上创建了一个索引。我认为您的查询和数据库状态目前处于最优化的形式。只有消除托管服务提供商施加的超时限制才能解决您的问题。

于 2013-04-20T09:22:38.013 回答