我有LINQ查询检查查询结果并结束语句。该数据库有大约600k的数据。以下是LINQ查询和if语句。
var feetypelist = from feetype in dbDataContext.tbl_fee_types
orderby feetype.seq
select feetype.id;
foreach (var fty in feetypelist)
{
var checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
orderby fee.seq
select fee;
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
&& fee.country == country
orderby fee.seq
select fee;
}
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr.Equals("DOM") && fee.dep.Equals("DOM")) ||
(fee.arr.Equals("*") && fee.dep == dep) || (fee.arr == arr && fee.dep.Equals("*")))
&& fee.feetypeid == fty
orderby fee.seq
select fee;
if (checkFeeCharges.Count() == 0)
{
var country_route = from route in dbDataContext.tbl_country_routes
where route.origin_airport_cd == arr && route.destination_airport_cd == dep
select route;
if (country_route.Count() >= 1)
{
foreach (var c in country_route)
{
if (c.air_asiax == 'Y')
{
//con_flight = "Y";
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == "AAX" && fee.dep == "AAX") || (fee.arr == "*" && fee.dep == dep) ||
(fee.arr == arr && fee.dep == "*")) && fee.feetypeid == fty
orderby fee.seq
select fee;
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*") ||
(fee.arr == country && fee.dep == country)) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
}
else
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*") ||
(fee.arr == country && fee.dep == country)) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
}
}
else
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*")) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
}
}
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*")) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
查询执行需要一段时间才能完成,不知道如何优化此查询。
返回json请求
if (checkFeeCharges.Any())
{
List<FeeAndChargesModel_Fee_Schedule> feeTable = new List<FeeAndChargesModel_Fee_Schedule>();
foreach (var p in checkFeeCharges)
{
feeTable.Add(
new FeeAndChargesModel_Fee_Schedule()
{
arr = FlightScheduleAPIController.GetCountryName(arr, siteId),
dep = FlightScheduleAPIController.GetCountryName(dep, siteId),
country = p.country,
feedesc = p.feedesc,
feetype = p.feetype,
currency = p.currency,
value = p.value,
remark = p.remark
}
);
label = p.feetype;
}
mainJson.Add(
new FeeAndChargesModel_Main
{
label = label,
con_flight = FlightScheduleAPIController.GetCountryName(GetConnectingFlight(dep, arr), siteId),
details = feeTable
}
);
}
}
return mainJson;
答案 0 :(得分:1)
好的,所以这段代码真的很难阅读,但我们可以给你一些建议。
首先我注意到第一个sql语句被执行
var checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
orderby fee.seq
select fee;
如果没有返回任何内容
if (checkFeeCharges.Count() == 0)
{
它执行的sql查询比第一个查询更具体。它具有所有相同的AND语句+另一个。如果第一个查询没有返回任何内容,那么期望(所有事物不变)应该是第二个不返回任何内容。如果是这样,为什么呢?
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
&& fee.country == country
orderby fee.seq
select fee;
}
我个人会尝试理解或解决以下问题
1 预期的结果集大小是多少,我可以检索“少量”记录并在内存中处理这些记录。我需要了解结果集是否会随着时间的推移而增长,以及它的最小,最大类型边界。
2 是否有更好的数据库结构,我可以重构使用的代码,这将使这个查询更容易和更有效。
第3 强> 为了实际能够优化这个查询,我会尝试直接在sql中编写它,并使用explain来帮助理解sql数据库正在做什么,正在使用什么索引以及返回结果集的大小每个查询。
。我也相信你应该能够将你所拥有的大量查询合并到一个表达式中。
这可能不完全正确,但作为演示应该没问题
from fee in dbDataContext.tbl_fee_schedules
where (fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
&& fee.country == country) || (fee.site_id == siteId && fee.country == country &&
((fee.arr == "AAX" && fee.dep == "AAX") || (fee.arr == "*" && fee.dep == dep) ||
(fee.arr == arr && fee.dep == "*")) && fee.feetypeid == fty)
|| ( ..... ) | ( .... )
从我在那里可以看到你需要一些连接或子选择,这就是为什么在sql中尝试它会最快。还有一些linq2sql / ORM分析工具可能有助于诊断。
答案 1 :(得分:0)
很难说如何优化它,因为你在这里有很多重复。我开始尝试减少它。
要改变的一个显而易见的事情是:
if (checkFeeCharges.Count() == 0)
每次调用它时都会枚举整个查询。检查同样事情的便宜得多的方式:
if (!checkFeeCharges.Any())
这只会枚举查询中的一个结果,以确定它是否为空。