C#程序:
void Main()
{
int[] r={4,5,11};
var query = from a in Sales where 1==0 select a.ID;
foreach(int n in r)
{
query = query.Concat(from a in Pig where a.ID==n select a.ID);
}
Console.Write(query);
}
query 生成的sql语句:
-- Region Parameters
DECLARE @p0 Int = 0
DECLARE @p1 Int = 11
DECLARE @p2 Int = 11
DECLARE @p3 Int = 11
-- EndRegion
SELECT [t6].[ID]
FROM (
SELECT [t4].[ID]
FROM (
SELECT [t2].[ID]
FROM (
SELECT [t0].[ID]
FROM [Sales] AS [t0]
WHERE @p0 = 1
UNION ALL
SELECT [t1].[ID]
FROM [Pig] AS [t1]
WHERE [t1].[ID] = @p1
) AS [t2]
UNION ALL
SELECT [t3].[ID]
FROM [Pig] AS [t3]
WHERE [t3].[ID] = @p2
) AS [t4]
UNION ALL
SELECT [t5].[ID]
FROM [Pig] AS [t5]
WHERE [t5].[ID] = @p3
) AS [t6]
正确的结果应该是@p1=4,@p2=5,@p3=11,而实际生成的sql为什么都是11?
其实我原本的目的是:
var query = from a in Sales where a.ID==4 || a.ID==5 || a.ID==11 select a.ID;
但用or语句导致效率很低,所以想改为union all方式,但生成的sql不正确.
foreach(int n in r) { var x = n; query = query.Concat(from a in Pig where a.ID==x select a.ID); }
foreach开始加一句就可以了。这个是lambda表达式闭包引起的。
果然是这样! 非常感谢!
不过类似这样的sql语句感觉效率真的好低,不知怎么优化?
其实就是对同一个字段或条件判断.
select * from dbo.Pig as t where t.ID=1 or t.ID=2 or t.ID=3 ...
@settan: 用 Queryable.Contains 方法,(如果我没记错的话)会被翻译成IN查询.
var ids = new int[] { 4, 5, 11 }; query = from a in Sales where ids.Contains(a.ID);
@水牛刀刀: 测试了一下:
1.用Contains,生成in语句的sql:
var query = from a in Pig where r.Contains(a.TypeID) select a;
2.用or,生成or语句的sql:
var query = from a in Pig where a.TypeID==4 || a.TypeID==5 || a.TypeID==11 select a;
3.用Concat,生成union all 语句的sql:
int[] r={4,5,11};
var query = from a in Pig where 1==0 select a;
foreach(int n in r)
{
int x = n;
query = query.Concat(from a in Pig where a.TypeID==x select a);
}
以上三种方式,第一种和第二种方式效率差不多,都需要14s左右,
还是第三种方式效率高一些,只要4s左右.但感觉还是达不到期望的效率.
难道就没有更好的办法了吗?
@settan: 14秒?开玩笑吧...就这么个简单的select要这么久,你是在侮辱微软的程序员啊.. 你就是根据id select记录出来?还是你这个问题是简化过的.
@水牛刀刀: 不是根据ID,而是根据TypeID,而且查询对象Pig是个视图
@settan: UNION确实可能比OR快(同理IN),看这里:http://stackoverflow.com/questions/5639710/union-all-vs-or-condition-in-sql-server-query
@settan: 猜测是根据TypeID去获取到记录是很快的,因此多个这样的操作UNION起来也比较快。而OR破坏了一些“快的因素”,例如视图索引。同理IN。
你这叫效率高? 完全不敢认同
效率的确很低,可是应该怎么优化呢?