是没有'WHERE param = value'语句的查询吗?
为此简单而道歉...
答案 0 :(得分:8)
无界查询是搜索条件不是特别具体的查询,因此很可能返回非常大的结果集。没有WHERE子句的查询肯定会属于这个类别,但我们暂时考虑其他一些可能性。假设我们有如下表格:
CREATE TABLE SALES_DATA
(ID_SALES_DATA NUMBER PRIMARY KEY,
TRANSACTION_DATE DATE NOT NULL
LOCATION NUMBER NOT NULL,
TOTAL_SALE_AMOUNT NUMBER NOT NULL,
...etc...);
CREATE TABLE LOCATION
(LOCATION NUMBER PRIMARY KEY,
DISTRICT NUMBER NOT NULL,
...etc...);
假设我们想要引入特定交易,并且我们知道销售的ID:
SELECT * FROM SALES_DATA WHERE ID_SALES_DATA = <whatever>
在这种情况下,查询是有界的,我们可以保证它会拉入一行或零行。
有界查询的另一个例子,但结果集很大,是23区主任说“我想看看去年每天在我所在地区的每家商店的总销售额”,就像
SELECT LOCATION, TRUNC(TRANSACTION_DATE), SUM(TOTAL_SALE_AMOUNT)
FROM SALES_DATA S,
LOCATION L
WHERE S.TRANSACTION_DATE BETWEEN '01-JAN-2009' AND '31-DEC-2009' AND
L.LOCATION = S.LOCATION AND
L.DISTRICT = 23
GROUP BY LOCATION,
TRUNC(TRANSACTION_DATE)
ORDER BY LOCATION,
TRUNC(TRANSACTION_DATE)
在这种情况下,查询应返回区域23中每个商店的365(或更少,如果商店不是每天开放)行。如果区域中有25个商店,它将返回9125行或更少。
另一方面,假设我们的销售副总裁想要一些数据。他/她/它不太确定想要什么,但他/她/它非常肯定无论发生在一年的前六个月......不太确定哪个一年......也不确定这个位置 - 可能是在23区(他/她与过去6年经营23区的个人发生了争执,自那场高尔夫锦标赛以来......好吧,没关系......但是如果问题可以挂在23区的导演的门上,那么就这样吧!)......当然他/她/它想要所有的细节,并把它放在他/她/它的桌子很甜!因此我们得到一个类似于
的查询SELECT L.DISTRICT, S.LOCATION, S.TRANSACTION_DATE,
S.something, S.something_else, S.some_more_stuff
FROM SALES_DATA S,
LOCATIONS L
WHERE EXTRACT(MONTH FROM S.TRANSACTION_DATE) <= 6 AND
L.LOCATION = S.LOCATION
ORDER BY L.DISTRICT,
S.LOCATION
这是无限查询的示例。它会返回多少行?好问题 - 这取决于商业条件如何,开放的地点数量,2月份的天数等等。
更简单地说,如果你可以查看一个查询并且非常清楚它将返回多少行(即使这个数字可能相对较大),查询也是有界限的。如果你做不到,那就没有限制了。
分享并享受。
答案 1 :(得分:0)
http://hibernatingrhinos.com/Products/EFProf/learn#UnboundedResultSet
无界结果集是执行查询的位置,并未明确限制查询返回结果的数量。通常,这意味着应用程序假定查询始终只返回几条记录。这在开发和测试中都很有效,但它是一个等待在生产中爆炸的定时炸弹。
查询可能会突然开始返回数千行,在某些情况下,它可能会返回数百万行。这会导致数据库服务器,应用程序服务器和网络上的负载增加。在许多情况下,它可以使整个系统停止运行,通常以应用程序服务器因内存不足错误而崩溃而结束。
以下是将触发无界结果集警告的查询的一个示例:
var query = from post in blogDataContext.Posts
where post.Category == "Performance"
select post;
如果性能类别有很多帖子,我们将加载所有帖子,这可能不是预期的。通过使用Take()方法使用分页可以很容易地解决这个问题:
var query = (from post in blogDataContext.Posts
where post.Category == "Performance"
select post)
.Take(15);
现在我们确信我们只需要处理可预测的小结果集,如果我们需要处理所有这些结果集,我们可以根据需要翻阅记录。分页是使用Skip()方法实现的,该方法指示实体框架在进入下一页之前跳过(在数据库级别)N条记录。
但是直接遍历对象图还存在另一个常见的无界结果集问题,如下例所示:
var post = postRepository.Get(id);
foreach (var comment in post.Comments)
{
// do something interesting with the comment
}
在这里,我们再次加载整个集合,而不考虑结果集的大小。在遍历对象图时,实体框架不提供对集合进行分页的好方法。建议您对集合的内容发出单独的显式查询,这样您就可以浏览该集合,而无需将太多数据加载到内存中。