sql – 对25万行的查询需要53秒

前端之家收集整理的这篇文章主要介绍了sql – 对25万行的查询需要53秒前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
查询正在运行的框是在数据中心中运行的专用服务器.

AMD Opteron 1354四核2.20GHz
2GB内存
Windows Server 2008 x64(是的,我知道我只有2GB的内存,当项目启动时我升级到8GB).

所以我经历了一个表,创建了250,000个虚拟行,真正压力测试一些LINQ to sql生成查询,并确保它们不会很糟糕,我注意到其中一个是在花费大量的时间.

我有这个查询下降到17秒的索引,但我删除了他们为了这个答案从头到尾.只有索引是主键.

Stories table --
[ID] [int] IDENTITY(1,1) NOT NULL,[UserID] [int] NOT NULL,[CategoryID] [int] NOT NULL,[VoteCount] [int] NOT NULL,[CommentCount] [int] NOT NULL,[Title] [nvarchar](96) NOT NULL,[Description] [nvarchar](1024) NOT NULL,[CreatedAt] [datetime] NOT NULL,[UniqueName] [nvarchar](96) NOT NULL,[Url] [nvarchar](512) NOT NULL,[LastActivityAt] [datetime] NOT NULL,Categories table --
[ID] [int] IDENTITY(1,[ShortName] [nvarchar](8) NOT NULL,[Name] [nvarchar](64) NOT NULL,Users table --
[ID] [int] IDENTITY(1,[Username] [nvarchar](32) NOT NULL,[Password] [nvarchar](64) NOT NULL,[Email] [nvarchar](320) NOT NULL,

目前在数据库中有1个用户,1个类别和25万个故事,我试图运行这个查询.

SELECT TOP(10) *
FROM Stories
INNER JOIN Categories ON Categories.ID = Stories.CategoryID
INNER JOIN Users ON Users.ID = Stories.UserID
ORDER BY Stories.LastActivityAt

查询需要52秒运行,cpu使用率徘徊在2-3%,Membery是1.1GB,900MB可用,但磁盘使用似乎失控.这是@ 100MB /秒,其中有2/3写入tempdb.mdf,其余的是从tempdb.mdf读取.

现在有趣的部分…

SELECT TOP(10) *
FROM Stories
INNER JOIN Categories ON Categories.ID = Stories.CategoryID
INNER JOIN Users ON Users.ID = Stories.UserID

SELECT TOP(10) *
FROM Stories
INNER JOIN Users ON Users.ID = Stories.UserID
ORDER BY Stories.LastActivityAt

SELECT TOP(10) *
FROM Stories
INNER JOIN Categories ON Categories.ID = Stories.CategoryID
ORDER BY Stories.LastActivityAt

这些查询中的所有3个都是即时的.

执行计划第一次查询.
http://i43.tinypic.com/xp6gi1.png

Exec计划其他3个查询(按顺序).
http://i43.tinypic.com/30124bp.png
http://i44.tinypic.com/13yjml1.png
http://i43.tinypic.com/33ue7fb.png

任何帮助将不胜感激.

添加索引后的Exec计划(再次下降到17秒).
http://i39.tinypic.com/2008ytx.png

我收到了所有人的很多有用的反馈,我感谢你,我尝试了一个新的角度.我查询我需要的故事,然后在单独的查询获取类别和用户,并且有3个查询只需要250ms …我不明白这个问题,但是如果它的工作原理,并且在250ms的时间,我会坚持下去这是我用来测试这个的代码.

DBDataContext db = new DBDataContext();
Console.ReadLine();

Stopwatch sw = Stopwatch.StartNew();

var stories = db.Stories.OrderBy(s => s.LastActivityAt).Take(10).ToList();
var storyIDs = stories.Select(c => c.ID);
var categories = db.Categories.Where(c => storyIDs.Contains(c.ID)).ToList();
var users = db.Users.Where(u => storyIDs.Contains(u.ID)).ToList();

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

解决方法

尝试在Stories.LastActivityAt上添加一个索引.我认为执行计划中的聚簇索引扫描可能是由于排序.

编辑:
由于我的查询在一瞬间返回只有几个字节长,但已经运行了5分钟,并且仍然在我添加一个2K varchar后,我认为米奇有一点.该数据的数量随机混乱的,但这可以在查询中修复.

尝试将连接,排序和顶部(10)放在视图或嵌套查询中,然后连接到故事表,以获取剩余的数据,只需要您需要的10行.

喜欢这个:

select * from 
(
    SELECT TOP(10) id,categoryID,userID
    FROM Stories
    ORDER BY Stories.LastActivityAt
) s
INNER JOIN Stories ON Stories.ID = s.id
INNER JOIN Categories ON Categories.ID = s.CategoryID
INNER JOIN Users ON Users.ID = s.UserID

如果您在LastActivityAt上有一个索引,则应该运行得非常快.

猜你在找的MsSQL相关文章