2013-06-25 53 views
0

此查詢速度非常慢。可以幫助我不知道從哪裏開始。當刪除.Include(「Pessoa」)時,返回速度非常快。慢速LINQ查詢與兩個實體

[Table("Pessoa")] 
public class Pessoa 
{ 

    public int PessoaId { get; set; } 

    public string NomPessoa { get; set; } 

    public string FlgTipoPessoa { get; set; } 

    public DateTime DatCadastro { get; set; } 

    public string ObsPessoa { get; set; } 

    public virtual ICollection<Endereco> Enderecos { get; set; } 

    public Pessoa() 
    { 
     Enderecos = new List<Endereco>(); 
    } 

} 

[Table("PessoaFisica")] 
public class PessoaFisica : Pessoa 
{ 

    public string NumCpf { get; set; } 

    public string NumRg { get; set; } 

    public DateTime? DatNascimento { get; set; } 

    public string FlgSexo { get; set; } 

} 

[Table("PessoaJuridica")] 
public class PessoaJuridica : Pessoa 
{ 
    public string NumCnpj { get; set; } 

    public string NumInscricaoEstadual { get; set; } 

    public string NumInscricaoMunicipal { get; set; } 

} 

[Table("Funcionario")] 
public class Funcionario : PessoaFisica 
{ 
    public DateTime DatAdmissao { get; set; } 
    public DateTime? DatDemissao { get; set; } 
    public decimal PercRoyalty { get; set; } 
} 

[Table("FluxoDeCaixa")] 
public class FluxoDeCaixa 
{ 
    public int FluxoDeCaixaId { get; set; } 

    public int PlanoDeContasId { get; set; } 
    public PlanoDeContas PlanoDeContas { get; set; } 

    public string DscFluxoDeCaixa { get; set; } 

    public int FuncionarioId { get; set; } 
    [ForeignKey("FuncionarioId")] 
    public Funcionario Funcionario { get; set; } 


    public decimal ValFluxoDeCaixa { get; set; } 
    public DateTime DatEmissao { get; set; } 
    public DateTime DatVencimento { get; set; } 
    public DateTime DatFluxo { get; set; } 

    public int PessoaId { get; set; } 
    [ForeignKey("PessoaId")] 
    public virtual Pessoa Pessoa { get; set; } 

    public string NumDocto { get; set; } 
    public string NumCheque { get; set; } 
    public string FlgSituacaoCheque { get; set; } 
    public string ObsFluxoDeCaixa { get; set; }   
} 

public override IQueryable<Entity.Modelos.FluxoDeCaixa> Filtro(System.Linq.Expressions.Expression<System.Func<Entity.Modelos.FluxoDeCaixa, bool>> expressao) 
    { 
     return _contexto.FluxoDeCaixa.Include("Pessoa").Where(expressao); 
    } 

.Filtro(f => f.DatFluxo >= dataInicial.Date && f.DatFluxo <= dataFinal.Date).ToList(); 

這是由實體框架生成的查詢,我不明白爲什麼使用這麼多左連接。我相信這是慢慢的原因。

{SELECT 
[Extent1].[FluxoDeCaixaId] AS [FluxoDeCaixaId], 
[Extent1].[PlanoDeContasId] AS [PlanoDeContasId], 
[Extent1].[DscFluxoDeCaixa] AS [DscFluxoDeCaixa], 
[Extent1].[FuncionarioId] AS [FuncionarioId], 
[Extent1].[ValFluxoDeCaixa] AS [ValFluxoDeCaixa], 
[Extent1].[DatEmissao] AS [DatEmissao], 
[Extent1].[DatVencimento] AS [DatVencimento], 
[Extent1].[DatFluxo] AS [DatFluxo], 
[Extent1].[PessoaId] AS [PessoaId], 
[Extent1].[NumDocto] AS [NumDocto], 
[Extent1].[NumCheque] AS [NumCheque], 
[Extent1].[FlgSituacaoCheque] AS [FlgSituacaoCheque], 
[Extent1].[ObsFluxoDeCaixa] AS [ObsFluxoDeCaixa], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN N'2X' WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN N'2X0X' WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN N'2X0X0X' ELSE N'2X1X' END AS [C1], 
[Join3].[PessoaId1] AS [PessoaId1], 
[Join3].[NomPessoa] AS [NomPessoa], 
[Join3].[FlgTipoPessoa] AS [FlgTipoPessoa], 
[Join3].[DatCadastro] AS [DatCadastro], 
[Join3].[ObsPessoa] AS [ObsPessoa], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN [Join3].[NumCpf] WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[NumCpf] END AS [C2], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN [Join3].[NumRg] WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[NumRg] END AS [C3], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS datetime) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN [Join3].[DatNascimento] WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[DatNascimento] END AS [C4], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN [Join3].[FlgSexo] WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[FlgSexo] END AS [C5], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS datetime) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN CAST(NULL AS datetime) WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[DatAdmissao] END AS [C6], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS datetime) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN CAST(NULL AS datetime) WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[DatDemissao] END AS [C7], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS decimal(18,2)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN CAST(NULL AS decimal(18,2)) WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN [Join3].[PercRoyalty] END AS [C8], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN CAST(NULL AS nvarchar(1)) ELSE [Join3].[NumCnpj] END AS [C9], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN CAST(NULL AS nvarchar(1)) ELSE [Join3].[NumInscricaoEstadual] END AS [C10], 
CASE WHEN ((NOT (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL))) AND (NOT (([Join3].[C12] = 1) AND ([Join3].[C12] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C11] = 1) AND ([Join3].[C11] IS NOT NULL) AND (NOT (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)))) THEN CAST(NULL AS nvarchar(1)) WHEN (([Join3].[C2] = 1) AND ([Join3].[C2] IS NOT NULL)) THEN CAST(NULL AS nvarchar(1)) ELSE [Join3].[NumInscricaoMunicipal] END AS [C11] 
FROM [FluxoDeCaixa] AS [Extent1] 
INNER JOIN (SELECT [Extent2].[PessoaId] AS [PessoaId1], [Extent2].[NomPessoa] AS [NomPessoa], [Extent2].[FlgTipoPessoa] AS [FlgTipoPessoa], [Extent2].[DatCadastro] AS [DatCadastro], [Extent2].[ObsPessoa] AS [ObsPessoa], [Project1].[PessoaId] AS [PessoaId2], [Project1].[NumCnpj] AS [NumCnpj], [Project1].[NumInscricaoEstadual] AS [NumInscricaoEstadual], [Project1].[NumInscricaoMunicipal] AS [NumInscricaoMunicipal], [Project1].[C1] AS [C12], [Project3].[PessoaId] AS [PessoaId3], [Project3].[NumCpf] AS [NumCpf], [Project3].[NumRg] AS [NumRg], [Project3].[DatNascimento] AS [DatNascimento], [Project3].[FlgSexo] AS [FlgSexo], [Project3].[C1] AS [C11], [Project3].[DatAdmissao] AS [DatAdmissao], [Project3].[DatDemissao] AS [DatDemissao], [Project3].[PercRoyalty] AS [PercRoyalty], [Project3].[C2] AS [C2] 
    FROM [Pessoa] AS [Extent2] 
    LEFT OUTER JOIN (SELECT 
     [Extent3].[PessoaId] AS [PessoaId], 
     [Extent3].[NumCnpj] AS [NumCnpj], 
     [Extent3].[NumInscricaoEstadual] AS [NumInscricaoEstadual], 
     [Extent3].[NumInscricaoMunicipal] AS [NumInscricaoMunicipal], 
     cast(1 as bit) AS [C1] 
     FROM [PessoaJuridica] AS [Extent3]) AS [Project1] ON [Extent2].[PessoaId] = [Project1].[PessoaId] 
    LEFT OUTER JOIN (SELECT 
     [Extent4].[PessoaId] AS [PessoaId], 
     [Extent4].[NumCpf] AS [NumCpf], 
     [Extent4].[NumRg] AS [NumRg], 
     [Extent4].[DatNascimento] AS [DatNascimento], 
     [Extent4].[FlgSexo] AS [FlgSexo], 
     cast(1 as bit) AS [C1], 
     [Project2].[DatAdmissao] AS [DatAdmissao], 
     [Project2].[DatDemissao] AS [DatDemissao], 
     [Project2].[PercRoyalty] AS [PercRoyalty], 
     CASE WHEN (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)) THEN cast(1 as bit) WHEN (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL))) THEN cast(0 as bit) END AS [C2] 
     FROM [PessoaFisica] AS [Extent4] 
     LEFT OUTER JOIN (SELECT 
      [Extent5].[PessoaId] AS [PessoaId], 
      [Extent5].[DatAdmissao] AS [DatAdmissao], 
      [Extent5].[DatDemissao] AS [DatDemissao], 
      [Extent5].[PercRoyalty] AS [PercRoyalty], 
      cast(1 as bit) AS [C1] 
      FROM [Funcionario] AS [Extent5]) AS [Project2] ON [Extent4].[PessoaId] = [Project2].[PessoaId]) AS [Project3] ON [Extent2].[PessoaId] = [Project3].[PessoaId]) AS [Join3] ON [Extent1].[PessoaId] = [Join3].[PessoaId1] 
WHERE ([Extent1].[DatFluxo] >= @p__linq__0) AND ([Extent1].[DatFluxo] <= @p__linq__1)} 

回答

1

你的問題可能是由於使用表每類型(TPT)繼承您的數據模型。我現在正在爲類似的問題苦苦掙扎。爲了在基類型上進行選擇時實現正確的派生類型,除非使用OfType<>()方法,否則Entity Framework會將基類型表與所有可能的派生表連接起來。

context.BaseEntities.OfType<DerivedEntityX>();

我發現這是最好只在簡單情況下,不會有太多的派生類型和那裏只是其中的一個繼承深度使用TPT。您在哪裏使用TPT嘗試並僅執行簡單的查詢。您可能會發現預生成視圖可能會減少您的初始冷查詢執行時間。投影到匿名類型或視圖模型,您可以選擇必要的屬性和/或使用方法,這對於提高性能也很有用。當然,您也可以考慮使用Table Per Heirarchy(TPH),以便所有派生類型映射到一個表。

+0

我不知道。 – davidterra

0

首先,如果你不需要查詢佩索阿,那就不要包括它。

其次,這可能是因爲你的佩索阿實體的下列財產的:

public virtual ICollection<Endereco> Enderecos { get; set; } 

既然你宣佈Enderecos虛擬,它會延遲加載每次查詢佩索阿實體的時間。

請閱讀this鏈接瞭解有關加載相關屬性的更多信息。

+0

我刪除了Enderecos但沒有解決。 – davidterra

0

不知道你正在使用的EF版本,但

1)在DB正確的索引,生成SQL作爲有效載荷的使用(修改硬編碼參數): Using Database Engine Tuning Advisor

2)如果你正在使用ObjectContext的直接那麼這可能加快速度(取決於如何大的日期範圍),然後修改Filtro體是這樣的:

var dataList= _contexto.FluxoDeCaixa.Where(expressao).ToList(); 

for (int x = 0; x < dataList.Count; x++) 
    _contexto.LoadProperty(dataList[x], p => p.Pessoa); 

return dataList; 

3)idealy,如果你想獲得最大的性能,重做,這樣你就不需要回覆把每一個列,返回只需要什麼樣的:

_contexto.FluxoDeCaixa.Select(t => new { t.DatFluxo , t.DatVencimento}).Where ....