2

我正在使用 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

在低评级的网站上没有问题,而且效果很好。但是在像 100000 行这样大的数据库和每天有 2000000 个单用户的网站中,它会崩溃。SqlTimeout它在三个页面之一引发异常。因此,当我单击一个页面时,几乎所有页面都给出了上述异常。

我检查了硬件性能,处理器消耗为 I7 3.6 GHZ 的 %70,内存消耗为 1.5 GB。但是有更多的空内存。我该如何克服这个问题?

任何帮助将不胜感激。

4

2 回答 2

1

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

我怀疑连接饥饿是一个问题——设置connection pool max size超过 32k 是没有意义的,并发 SQL 连接也将取决于与.Net 线程相关的因素。

我真的不明白为什么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

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

于 2013-10-23T15:17:27.640 回答
1

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

于 2013-10-23T15:09:22.527 回答