简体   繁体   English

使用 IN 而不是 JOIN 的 EF4 性能

[英]EF4 Performance using IN instead of JOIN

Is there any performance issue to be aware about using this sql statement generated by EF使用 EF 生成的 sql 语句是否有任何性能问题需要注意

C# code: C# 代码:

 public IQueryable<Lugar> NearestPOI(double lat, double lng, int> distance)
            {
                System.Data.Objects.ObjectResult<Int32?> AllowedPois = dbContext.SP_NearestPOI(lat, lng, 100000);


                IQueryable<Lugar> POI = from c in dbContext.Lugars
                          where AllowedPois.Contains(c.id)
                          select c;

                return POI;
            }

EF4 Generated query: EF4 生成的查询:

SELECT 
[Extent1].[id] AS [id], 
[Extent1].[empresaId] AS [empresaId], 
[Extent1].[usuarioId] AS [usuarioId], 
[Extent1].[name] AS [name], 
[Extent1].[description] AS [description], 
[Extent1].[lat] AS [lat], 
[Extent1].[lng] AS [lng],
[Extent1].[logoThumbnail] AS [logoThumbnail], 
[Extent1].[imageType] AS [imageType]
FROM [dbo].[Lugares] AS [Extent1]
WHERE [Extent1].[id] IN (1,2,3,4,5,6,7)

My concern is about doing the AllowedPois query as a separate one instaed of using the regular approach on pure SQL syntax that would be something like:我担心将 AllowedPois 查询作为一个单独的查询,而不是在纯 SQL 语法上使用常规方法,例如:

SELECT * from dbo.Lugares  L join dbo.NearestPOI(9.105306627167566,-79.38148587942118,100000) NL
on L.id = NL.id

As im using EF4 for this project I would like to stick with it and do not use string concatenation for the querys.由于我在这个项目中使用 EF4,我想坚持使用它,并且不要对查询使用字符串连接。 I tried to generate a more compelling query using this approach:我尝试使用这种方法生成更引人注目的查询:

var POI = from c in dbContext.Lugars
          join i in dbContext.SP_NearestPOI(lat, lng, 100000) on c.id  equals i.Value
          select c;

But it give out a really messy query with N number of unions that increments with the number of allowedPois:但它给出了一个非常混乱的查询,其中有 N 个联合,随着 allowedPois 的数量增加:

SELECT 
[Extent1].[id] AS [id], 
[Extent1].[empresaId] AS [empresaId], 
[Extent1].[usuarioId] AS [usuarioId], 
[Extent1].[name] AS [name], 
[Extent1].[description] AS [description], 
[Extent1].[lat] AS [lat], 
[Extent1].[lng] AS [lng], 
[Extent1].[logoThumbnail] AS [logoThumbnail], 
[Extent1].[imageType] AS [imageType]
FROM  [dbo].[Lugares] AS [Extent1]
INNER JOIN  (SELECT 
    [UnionAll5].[C1] AS [C1]
    FROM  (SELECT 
        [UnionAll4].[C1] AS [C1]
        FROM  (SELECT 
            [UnionAll3].[C1] AS [C1]
            FROM  (SELECT 
                [UnionAll2].[C1] AS [C1]
                FROM  (SELECT 
                    [UnionAll1].[C1] AS [C1]
                    FROM  (SELECT 
                        1 AS [C1]
                        FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
                    UNION ALL
                        SELECT 
                        2 AS [C1]
                        FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
                UNION ALL
                    SELECT 
                    3 AS [C1]
                    FROM  ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]
            UNION ALL
                SELECT 
                4 AS [C1]
                FROM  ( SELECT 1 AS X ) AS [SingleRowTable4]) AS [UnionAll3]
        UNION ALL
            SELECT 
            5 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable5]) AS [UnionAll4]
    UNION ALL
        SELECT 
        6 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable6]) AS [UnionAll5]
UNION ALL
    SELECT 
    7 AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable7]) AS [UnionAll6] ON [Extent1].[id] = [UnionAll6].[C1]

Any idea on how to improve this operation or should I stick with my actual solution using the separate query for the allowedPois?关于如何改进此操作的任何想法,或者我是否应该使用对 allowedPois 的单独查询坚持我的实际解决方案?

You really shouldn't use the join syntax in a LINQ query.您真的不应该在 LINQ 查询中使用连接语法。 Part of me wishes they didn't include the join operator in the C# language for LINQ because it just leads to confusion and tends to generate bad SQL like this.我的一部分希望他们没有在 LINQ 的 C# 语言中包含连接运算符,因为它只会导致混乱,并且往往会产生像这样的错误 SQL。 The reason being is that you almost are always joining in SQL to when you want to do a where clause or include that table in your results.原因是当您想要执行 where 子句或在结果中包含该表时,您几乎总是加入 SQL。 LINQ already has great support for this but you just have to think in the LINQ way and not the SQL way. LINQ 已经对此有很好的支持,但你只需要以 LINQ 的方式思考,而不是 SQL 的方式。 Your LINQ data model should have the relationships defined so you don't then need to redefine them through joins.您的 LINQ 数据 model 应该定义了关系,因此您不需要通过连接重新定义它们。 Doesn't totally apply here since you're using a sproc first but same principles apply.在这里并不完全适用,因为您首先使用的是 sproc,但同样的原则适用。 Your first LINQ query in C# is actually the efficient way to do it.您在 C# 中的第一个 LINQ 查询实际上是执行此操作的有效方法。

So, in case I wasn't clear.所以,如果我不清楚。 This is the right code.这是正确的代码。

public IQueryable<Lugar> NearestPOI(double lat, double lng, int> distance)
            {
                System.Data.Objects.ObjectResult<Int32?> AllowedPois = dbContext.SP_NearestPOI(lat, lng, 100000);


                IQueryable<Lugar> POI = from c in dbContext.Lugars
                          where AllowedPois.Contains(c.id)
                          select c;

                return POI;
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM