加入和哪里之间的区别

时间:2013-10-23 16:51:13

标签: c# .net linq entity-framework linq-to-entities

尝试使用多个连接来改进查询(查询时间为22秒: - /)。

在第一个中我看到一个linq查询,其中包含许多来自和限制的内容...当我看到生成的SQL时,我看到许多嵌套的'FROM(SELECT FROM(SELECT'...

我用JOIN改变了那段代码:

var groupPlans = (from client in Context.PERINSURANCECLIENT
    join person in Context.PERLEGALSTRUCTURE on client.MYIDENTITY_ID equals person.ID
    join groupAgreement in Context.GROUPAGREEMENT on client.ID equals groupAgreement.SUBSCRIBER_ID
    join groupPlan in Context.CNTPOLICY on groupAgreement.ID equals groupPlan.GROUPAGREEMENT_ID
    join product in Context.PROPRODUCT on groupPlan.MYPRODUCT_ID equals product.ID
    join pdv in Context.PERINSURANCEPARTNER on groupPlan.MYPOINTVENTE_ID equals pdv.ID

    where client.NSID == clientNSID
    && client.MYIDENTITY_NSID == legalNSID
    && groupAgreement.SUBSCRIBER_NSID == client.NSID
    && groupPlan.GROUPAGREEMENT_NSID == groupAgreement.NSID
    && groupPlan.NSID == NSIDgroupPlan
    && groupAgreement.NSID == NSIDGroupAgreement
        && groupPlan.MYPOINTVENTE_ID == pdv.ID

    && pdv.NSID == pdvNSID
    && groupPlan.MYGLOBALPOLICY_ID != 0 &&
    groupPlan.MYGLOBALPOLICY_NSID != 0 &&
    groupPlan.MYNEXTENDORSEMENT_ID == 0 &&
    (groupPlan.NATURE == 0 || groupPlan.NATURE == 1 || groupPlan.NATURE == 4 || groupPlan.NATURE == 2) &&
    (groupPlan.STATUS == 0 || groupPlan.STATUS == 1 || groupPlan.STATUS == 2 || groupPlan.STATUS == 3) &&
    groupPlan.MYPRODUCT_NSID == product.NSID &&
    groupPlan.MYPRODUCT_VERSION == -product.VERSION &&
    groupPlan.H_ISKILLED == 0
    &&
    product.NSID == productNSID
    orderby groupPlan.REFERENCE descending
    select new
    {
        LineOfBusiness = product.GSLINEOFBUSINESS,
        Produit = product.NAME,
        ProduitId = product.ID,
        Nature = groupPlan.NATURE,
        Etat = groupPlan.STATUS,
        EndorsmentNumber = groupPlan.ENDORSEMENTNUMBER,
        AssureName = person.NAME,
        Reference = groupPlan.REFERENCE,
        Id = groupAgreement.ID,
        PolicyNSID = groupPlan.NSID,
        NomPDV = pdv.NAME,
        CodePDV = pdv.CODEPOINTVENTE,
        PDVId = pdv.ID,
        IdClient = client.ID,
        IdIdentity = person.ID,
        Isreversed = groupPlan.ISREVERSED,
        PreviousEndorsemntID = groupPlan.MYPREVIOUSENDORSEMENT_ID,
        DateCreation = groupAgreement.CREATIONDATE,
        ValidityDate = groupPlan.DATEFINVALIDITEDEVIS,
        ReferenceAgreement = groupAgreement.REFERENCE,
        CodeSiret = person.SIRETNO,
        EffectiveDate = groupPlan.EFFECTIVEDATE,
    });

结论:同样的问题在这里没有提高绩效......

如果您有任何想法我如何改进此查询或关于JOIN与FROM WHERE的一些解释......

这里生成的sql(用Interllitrace捕获)

SELECT TOP (100) 
[Project1].[NSID] AS [NSID], 
[Project1].[GSLINEOFBUSINESS] AS [GSLINEOFBUSINESS], 
[Project1].[NAME1] AS [NAME], 
[Project1].[ID3] AS [ID], 
[Project1].[NATURE] AS [NATURE], 
[Project1].[STATUS] AS [STATUS], 
[Project1].[ENDORSEMENTNUMBER] AS [ENDORSEMENTNUMBER], 
[Project1].[NAME] AS [NAME1], 
[Project1].[REFERENCE1] AS [REFERENCE], 
[Project1].[ID2] AS [ID1], 
[Project1].[NAME2] AS [NAME2], 
[Project1].[CODEPOINTVENTE] AS [CODEPOINTVENTE], 
[Project1].[ID4] AS [ID2], 
[Project1].[ID] AS [ID3], 
[Project1].[ID1] AS [ID4], 
[Project1].[ISREVERSED] AS [ISREVERSED], 
[Project1].[MYPREVIOUSENDORSEMENT_ID] AS [MYPREVIOUSENDORSEMENT_ID], 
[Project1].[CREATIONDATE] AS [CREATIONDATE], 
[Project1].[DATEFINVALIDITEDEVIS] AS [DATEFINVALIDITEDEVIS], 
[Project1].[REFERENCE] AS [REFERENCE1], 
[Project1].[SIRETNO] AS [SIRETNO], 
[Project1].[EFFECTIVEDATE] AS [EFFECTIVEDATE]
FROM ( SELECT 
    [Filter1].[ID1] AS [ID], 
    [Filter1].[ID2] AS [ID1], 
    [Filter1].[NAME1] AS [NAME], 
    [Filter1].[SIRETNO] AS [SIRETNO], 
    [Filter1].[ID3] AS [ID2], 
    [Filter1].[REFERENCE1] AS [REFERENCE], 
    [Filter1].[CREATIONDATE1] AS [CREATIONDATE], 
    [Filter1].[NSID1] AS [NSID], 
    [Filter1].[REFERENCE2] AS [REFERENCE1], 
    [Filter1].[ENDORSEMENTNUMBER] AS [ENDORSEMENTNUMBER], 
    [Filter1].[NATURE] AS [NATURE], 
    [Filter1].[STATUS1] AS [STATUS], 
    [Filter1].[ISREVERSED] AS [ISREVERSED], 
    [Filter1].[EFFECTIVEDATE1] AS [EFFECTIVEDATE], 
    [Filter1].[MYPREVIOUSENDORSEMENT_ID] AS [MYPREVIOUSENDORSEMENT_ID], 
    [Filter1].[DATEFINVALIDITEDEVIS] AS [DATEFINVALIDITEDEVIS], 
    [Filter1].[ID4] AS [ID3], 
    [Filter1].[NAME2] AS [NAME1], 
    [Filter1].[GSLINEOFBUSINESS] AS [GSLINEOFBUSINESS], 
    [Extent6].[ID] AS [ID4], 
    [Extent6].[NAME] AS [NAME2], 
    [Extent6].[CODEPOINTVENTE] AS [CODEPOINTVENTE]
    FROM   (SELECT [Extent1].[NSID] AS [NSID2], [Extent1].[ID] AS [ID1], [Extent1].[MYIDENTITY_NSID] AS [MYIDENTITY_NSID], [Extent2].[ID] AS [ID2], [Extent2].[NAME] AS [NAME1], [Extent2].[SIRETNO] AS [SIRETNO], [Extent3].[NSID] AS [NSID3], [Extent3].[ID] AS [ID3], [Extent3].[REFERENCE] AS [REFERENCE1], [Extent3].[CREATIONDATE] AS [CREATIONDATE1], [Extent4].[NSID] AS [NSID1], [Extent4].[REFERENCE] AS [REFERENCE2], [Extent4].[ENDORSEMENTNUMBER] AS [ENDORSEMENTNUMBER], [Extent4].[NATURE] AS [NATURE], [Extent4].[STATUS] AS [STATUS1], [Extent4].[ISREVERSED] AS [ISREVERSED], [Extent4].[EFFECTIVEDATE] AS [EFFECTIVEDATE1], [Extent4].[MYPREVIOUSENDORSEMENT_ID] AS [MYPREVIOUSENDORSEMENT_ID], [Extent4].[DATEFINVALIDITEDEVIS] AS [DATEFINVALIDITEDEVIS], [Extent4].[MYPOINTVENTE_ID] AS [MYPOINTVENTE_ID], [Extent5].[NSID] AS [NSID4], [Extent5].[ID] AS [ID4], [Extent5].[NAME] AS [NAME2], [Extent5].[GSLINEOFBUSINESS] AS [GSLINEOFBUSINESS]
        FROM     [dbo].[PERINSURANCECLIENT] AS [Extent1]
        INNER JOIN [dbo].[PERLEGALSTRUCTURE] AS [Extent2] ON [Extent1].[MYIDENTITY_ID] = [Extent2].[ID]
        INNER JOIN [dbo].[GROUPAGREEMENT] AS [Extent3] ON ([Extent1].[ID] = [Extent3].[SUBSCRIBER_ID]) AND ([Extent3].[SUBSCRIBER_NSID] = [Extent1].[NSID])
        INNER JOIN [dbo].[CNTPOLICY] AS [Extent4] ON ([Extent3].[ID] = [Extent4].[GROUPAGREEMENT_ID]) AND ([Extent4].[GROUPAGREEMENT_NSID] = [Extent3].[NSID])
        INNER JOIN [dbo].[PROPRODUCT] AS [Extent5] ON ([Extent4].[MYPRODUCT_ID] = [Extent5].[ID]) AND ([Extent4].[MYPRODUCT_NSID] = [Extent5].[NSID])
        WHERE (cast(0 as decimal(18)) <> [Extent4].[MYGLOBALPOLICY_ID]) AND (0 <> [Extent4].[MYGLOBALPOLICY_NSID]) AND (cast(0 as decimal(18)) = [Extent4].[MYNEXTENDORSEMENT_ID]) AND ((0 =  CAST( [Extent4].[NATURE] AS int)) OR (1 =  CAST( [Extent4].[NATURE] AS int)) OR (4 =  CAST( [Extent4].[NATURE] AS int)) OR (2 =  CAST( [Extent4].[NATURE] AS int))) AND ((0 =  CAST( [Extent4].[STATUS] AS int)) OR (1 =  CAST( [Extent4].[STATUS] AS int)) OR (2 =  CAST( [Extent4].[STATUS] AS int)) OR (3 =  CAST( [Extent4].[STATUS] AS int))) AND (0 = [Extent4].[H_ISKILLED]) AND ([Extent4].[MYPRODUCT_VERSION] = ( -([Extent5].[VERSION]))) ) AS [Filter1]
    INNER JOIN [dbo].[PERINSURANCEPARTNER] AS [Extent6] ON [Filter1].[MYPOINTVENTE"

[编辑]

在数据库中进行一些调查后,我发现有太多的索引(1000个表的6000个索引)

1 个答案:

答案 0 :(得分:1)

SelectMany后跟Where在LINQ对象中很糟糕,因为它无法优化代码。在SQL中,from-from / where有足够的机会在数据库实际运行之前进行优化,因此实际上并不是那么多问题。由于这个转换以前是由DB完成的,所以你没有看到太多改进,正如我所期望的那样。

虽然连接本身比交叉产品快得多,但它们仍然不是最便宜的操作。完全可能只加入你拥有的所有数据(取决于所有表中的数据量)就是这么多,并且即使在合理的实现中也需要花费很多时间来执行。