我在表格中有以下列:
OrderId
CustomerId
TimeZoneOffset <-- in minutes
DateOrderUTC <-- This field is indexed
...
...
...
当用户过滤日期时,我需要考虑订单的时区。我知道,我可以只创建没有 UTC 的 DateOrder(在创建订单时使用它们的时区)。但这是给我的数据库。
这张表包含大约200万条记录。如果我使用下面的代码,它不会使用索引查找,因为它需要添加时区
return (from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
where (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) >= startDate) && (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) <= endDate)
select rec).Count();
所以,我的想法是为 startDate 添加 -1 天,为 endDate 添加 +1 天,以欺骗优化器使用索引。所以,代码看起来像这样:
startDate = startDate.AddDays(-1);
endDate = endDate.AddDays(1);
var vRecs = (from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
where (rec.DateOrderUTC >= startDate) && (rec.DateOrderUTC <= endDate)
select rec);
//I don't want to return the list first because it can be hundreds of thousands of records.
return ???; //how to do another filter here before returning the Count?
有什么想法吗?
提前感谢您的帮助...
您可以添加另一个
where
子句,甚至可以将其组合在第二个查询中。
var qRec1 = from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
where (rec.DateOrderUTC >= startDate) && (rec.DateOrderUTC <= endDate)
select rec;
var qRec2 = from rec in qRec1
where (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) >= startDate) && (DbFunctions.AddMinutes(rec.DateOrderUTC, rec.TimeZoneOffset) <= endDate)
select rec;
var count = qRec2.Count();
但是您应该真正使用单个查询并将 startDate/endDate 转换为 UTC,这样您就不会将列表达式包装在非 SARGable 表达式中,并且可以使用索引。
var qRec = from rec in dbctx.tblApprovalReferralPromoUsers.AsNoTracking()
where rec.DateOrderUTC >= DbFunctions.AddMinutes(startDate, -rec.TimeZoneOffset)
&& rec.DateOrderUTC < DbFunctions.AddMinutes(endDate,-rec.TimeZoneOffset)
select rec;