C# LINQ与经典asp的sql查询性能差异
我正在开发一个asp.net web forms 4.5网站, 我遇到了一个必须执行sql查询的问题 来自最初由经典asp编写的sql server 原始查询如下所示C# LINQ与经典asp的sql查询性能差异,c#,asp.net,sql-server,linq,asp-classic,C#,Asp.net,Sql Server,Linq,Asp Classic,我正在开发一个asp.net web forms 4.5网站, 我遇到了一个必须执行sql查询的问题 来自最初由经典asp编写的sql server 原始查询如下所示 select trait1, trait2, sum(qty) as qty from table2 right outer join table1 on (table1.col == table2.col) where table2.idx is null group by trait1, trait2 order by tr
select trait1, trait2, sum(qty) as qty from table2
right outer join table1 on (table1.col == table2.col)
where table2.idx is null
group by trait1, trait2
order by trait1, trait2
当我在写一个.net程序时,我试图重写这个查询。。。
像这样
var myHashSet = new HashSet<string>(table2.Select(c => c.col));
from item in table2
where !myHashSet.Contains(item.col)
group item.qty by new {item.trait1, item.trait2} into total
select new
{
trait1 = total.Key.trait1,
trait2 = total.Key.trait2,
qty = total.Sum()
} into anon
order by anon.qty descending
select anon
ps:按部分忽略订单。。这不重要
对于经典asp,需要1.5秒,但是对于c asp.net,
大约需要8秒钟
这些查询并不完全像那样,但几乎与我写的内容相似
我不明白为什么要花这么长时间。。
有人能告诉我为什么要花这么长时间以及我应该如何修复它吗?您不需要hashset,而是使用join,您的查询可能如下所示
var inner = from two in table2
join one in table1
on two.col equals one.col
group two by new
{
two.trait1,
two.trait2
} into total
select new
{
total.Key.trait1,
total.Key.trait2,
qty = total.Sum(p => p.qty)
};
编辑
为了完整起见,我还添加了一个左连接变量
var left = from two in table2
from one in
(
from temp in table1
where temp.col == two.col
select temp
).DefaultIfEmpty()
group two by new
{
two.trait1,
two.trait2
} into total
select new
{
total.Key.trait1,
total.Key.trait2,
qty = total.Sum(p => p.qty)
};
您不需要hashset,而是使用join,您的查询可能如下所示
var inner = from two in table2
join one in table1
on two.col equals one.col
group two by new
{
two.trait1,
two.trait2
} into total
select new
{
total.Key.trait1,
total.Key.trait2,
qty = total.Sum(p => p.qty)
};
编辑
为了完整起见,我还添加了一个左连接变量
var left = from two in table2
from one in
(
from temp in table1
where temp.col == two.col
select temp
).DefaultIfEmpty()
group two by new
{
two.trait1,
two.trait2
} into total
select new
{
total.Key.trait1,
total.Key.trait2,
qty = total.Sum(p => p.qty)
};
首先想到的是,您正在将第二个表中的所有内容加载到哈希集中,其中不限制任何内容,然后使用客户端操作检查表1中的每一行是否不匹配。这将比让数据库在原始查询中那样做效率要低得多。为什么不直接使用原稿呢?我想一定有一些拼写错误吧。其中c=>c.idx==c.idx?我曾尝试使用相同的查询,但多次导致内存不足错误,因此这就是我成功的方法。但也许我应该接受你的建议,对原版多加尝试。@DanDohotaru你说得对。我想我们不需要这样,只要用LINQ编写查询,方式与SQL类似,使用from join即可。您只需要使用非常低效的LINQ where哈希集,因此会出现性能问题。事实上,LINQ优化器可能会对您有所帮助。首先想到的是,您正在将第二个表中的所有内容加载到哈希集中,其中不限制任何内容,然后使用客户端操作检查表1中的每一行是否不匹配。这将比让数据库在原始查询中那样做效率要低得多。为什么不直接使用原稿呢?我想一定有一些拼写错误吧。其中c=>c.idx==c.idx?我曾尝试使用相同的查询,但多次导致内存不足错误,因此这就是我成功的方法。但也许我应该接受你的建议,对原版多加尝试。@DanDohotaru你说得对。我想我们不需要这样,只要用LINQ编写查询,方式与SQL类似,使用from join即可。您只需要使用非常低效的LINQ where哈希集,因此会出现性能问题。事实上,有些LINQ优化器可能会对您有所帮助。当然,但至少从原始描述中的小细节来看,正确的外部联接不会改变任何东西。。。但是请记住,至少对于我的答案,我将查询基于表2而不是表1。实际上,rene是正确的,我确实需要一个外部联接,但实际上我尝试了联接并成功了,现在只需1秒即可继续,我还感谢您的快速响应。谢谢很好,我还添加了左外连接变体,只是为了将来参考sakesure的东西,但至少从原始描述中的小细节来看,右外连接不会改变任何东西。。。但是请记住,至少对于我的答案,我将查询基于表2而不是表1。实际上,rene是正确的,我确实需要一个外部联接,但实际上我尝试了联接并成功了,现在只需1秒即可继续,我还感谢您的快速响应。谢谢太好了,我还添加了左外连接变量,只是为了将来参考