SQL Linq . take()从大型数据库中获取最近的20行数据,提高性能
本文关键字:20行 最近 数据 高性能 获取 take Linq 数据库 大型 SQL | 更新日期: 2023-09-27 18:06:00
我使用的是EntityFramework 6,我从Asp进行Linq查询。. NET服务器到azure sql数据库
我需要检索满足特定条件的最近20行
这是我的查询的一个粗略的例子
using (PostHubDbContext postHubDbContext = new PostHubDbContext())
{
DbGeography location = DbGeography.FromText(string.Format("POINT({1} {0})", latitude, longitude));
IQueryable<Post> postQueryable =
from postDbEntry in postHubDbContext.PostDbEntries
orderby postDbEntry.Id descending
where postDbEntry.OriginDbGeography.Distance(location) < (DistanceConstant)
select new Post(postDbEntry);
postQueryable = postQueryable.Take(20);
IOrderedQueryable<Post> postOrderedQueryable = postQueryable.OrderBy(Post => Post.DatePosted);
return postOrderedQueryable.ToList();
}
问题是,如果我的数据库中有10亿行呢?该查询是否会残忍地选择数百万行满足条件,然后得到其中的20行?或者它会聪明地意识到我只想要20行,因此它只会选择20行吗?
基本上我是如何使这个查询工作效率高的数据库有十亿行
根据http://msdn.microsoft.com/en-us/library/bb882641.aspx Take()函数延迟了流执行以及select语句。这意味着它应该相当于SQL中的TOP 20
, SQL将只从数据库中获取20行。
这个链接:http://msdn.microsoft.com/en-us/library/bb399342(v=vs.110).aspx显示Take在Linq-to-SQL中有直接的翻译。
所以你能做的唯一性能是在数据库中。就像@usr建议的那样,您可以使用索引来提高性能。此外,按排序顺序存储表也很有帮助(这可能是您按id排序的情况)。
为什么不试试呢?:)你可以检查sql,看看它生成了什么,然后看看sql的执行计划,看看它是否扫描了整个表
查看这个问题了解更多细节如何查看实体框架生成的SQL ?
这很难快速完成。您想要一个索引为您提供Id
上的排序顺序,但您想要一个不同的(空间)索引为您提供有效的过滤。创建一个同时满足这两个目标的索引是不可能的。
假设两个索引都存在:
如果过滤器是非常选择性的期望SQL Server"选择"所有行在这个过滤器为真,然后排序,然后给你前20。假设只有21行通过了筛选——那么这个策略显然是非常有效的。
如果过滤器不是选择性的 SQL Server将按照Id顺序遍历表,测试它所经过的每一行并输出前20行。假设过滤器适用于所有行,那么SQL Server只能输出它看到的前20行。非常快。
因此,对于100%或0%选择性,查询将很快。介于两者之间的是令人讨厌的混合物。如果你这样认为,这个问题需要进一步思考。你可能需要的不仅仅是一个聪明的索引策略。你需要更改应用程序
Btw,我们不需要DatePosted
的索引。DatePosted
的排序仅在将集合限制为20行之后进行。我们不需要索引来排序20行。