C# LINQ与经典asp的sql查询性能差异

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

我正在开发一个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 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秒即可继续,我还感谢您的快速响应。谢谢太好了,我还添加了左外连接变量,只是为了将来参考