Sql timeout异常,但最大池大小设置为1000000

时间:2013-10-23 15:06:09

标签: c# asp.net sql-server asp.net-mvc

我正在使用asp.net MVC4项目并使用SQL Server 2008.我的数据库表包含100000行。此外,连接字符串属性的最大池大小设置为1000000,池设置为true。

我的表格结构如下:

CREATE TABLE tblNews
(
ID int IDENTITY(1,1) NOT NULL,
Url nvarchar(300) UNIQUE NOT NULL,
PubDate datetime NOT NULL,
Active bit NOT NULL,
Hit int NOT NULL,
...
)

并且索引如下:

CREATE NONCLUSTERED INDEX indexTblNews_Url
ON tblNews(Url)

我的选择查询是:

CREATE PROC spNewsGet
   @Url nvarchar(300)
AS
   UPDATE tblNews
   SET Hit = Hit + 1
   WHERE Url = @Url
     AND PubDate > GETDATE()
     AND Active = 1;

   SELECT
      *
   FROM tblNews
   WHERE Url = @Url
     AND PubDate > GETDATE()
     AND Active = 1
   ORDER BY PubDate DESC

在低评级网站中没有问题,这完美无缺。但是在数据库这么大的10万行和每天200万单用户的网站上,它崩溃了。它会在三个页面中的一个页面上抛出SqlTimeout异常。当我点击一个页面时,几乎所有这些都给出了上述异常。

我检查过硬件性能和处理器消耗是I7 3.6 GHZ的%70,内存消耗是1.5 GB。但是有更多的空内存。我怎样才能克服这个问题?

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

您很可能正在使用SqlConnection。尝试将连接的ConnectionTimeout属性设置为0以指示无限超时。如果您没有使用SqlConnection,则可能会设置类似的属性。

答案 1 :(得分:1)

对于某些网站而言,它可以快速运行的一个可能原因是,对于大量网站,URL不再具有足够的选择性,以使现有索引能够正常工作。因此,UPDATE可能会升级到行锁之外,从而导致争用聚簇/非聚簇索引。

我怀疑连接饥饿是一个问题 - 将connection pool max size设置为超过32k是pointless,并发SQL连接还将取决于与.Net threads相关的因素。

我真的不明白为什么PubDate将来会过时,但如果PubDate > GETDATE()和/或Active = 1显着减少更新查询中的记录数量,那么我还会将这些字段中的一个或两个添加到索引中(如果适用),即:

CREATE NONCLUSTERED INDEX indexTblNews_Url
ON tblNews(Url, PubDate);

您还要复制查询 - 一次更新,一次选择。您可以通过临时表减少冗余并加入其中。

CREATE PROC spNewsGet
@Url nvarchar(300)
AS
  SELECT ID
  INTO #tmp
  FROM tblNews
  WHERE Url = @Url
  AND PubDate > GETDATE()
  AND Active = 1;

  UPDATE tblNews
  SET Hit = Hit + 1
  FROM tblNews INNER JOIN #tmp on #tmp.ID = tblNews.ID;

  -- Consider also using SET TRANSACTION ISOLATION SNAPSHOT or READ UNCOMMITTED here.
  SELECT tblNews.*
  FROM tblNews INNER JOIN #tmp on #tmp.ID = tblNews.ID
  ORDER BY PubDate DESC;
GO

最后,根据评论,您可以考虑在最终选择中删除隔离级别,前提是结果集不用于“事务关键”'的使用。