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);
解决方法
编辑:
由于我的查询在一瞬间返回只有几个字节长,但已经运行了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上有一个索引,则应该运行得非常快.