我正在使用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。但是有更多的空内存。我怎样才能克服这个问题?
非常感谢任何帮助。
答案 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
最后,根据评论,您可以考虑在最终选择中删除隔离级别,前提是结果集不用于“事务关键”'的使用。