-2

尝试改进具有多个连接的查询(查询需要 22 秒:-/)。

首先,我看到一个 linq 查询,其中包含许多 from 和 where 限制...当我看到流派的 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个索引)

4

1 回答 1

1

SelectMany其次Where在 LINQ to objects 中很糟糕,因为它无法优化代码。在 SQL 中,from-from/where 有足够的机会在 DB 实际运行之前对其进行优化,因此这并不是什么大问题。由于这种转换以前是由数据库完成的,因此您没有看到太大的改进,正如我所预料的那样。

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

于 2013-10-23T16:54:20.730 回答