Entity Framework: consulta em execução 'selecionar' sem motivo
-
19-09-2019 - |
Pergunta
Eu estou tendo alguns problemas com a estrutura de entidade. Estou executando uma simples escolha de um modo de exibição no banco de dados. No entanto, quando eu ver o SQL que EF gera, é executar a consulta duas vezes usando um escolher. É esta a maneira que é suposto para operar? Parece muito ineficiente.
var reads = (from rt in ctx.C2kReadsToTransfer
where rt.ReadDt > fromDate
&& rt.ReadDt < toDate
select rt);
Este é traduzido para o seguinte SQL
SELECT
[Extent1].[AMRID] AS [AMRID]
, [Extent1].[Comments] AS [Comments]
, [Extent1].[ExternalSystemType] AS [ExternalSystemType]
, [Extent1].[LastReadDt] AS [LastReadDt]
, [Extent1].[ReadDt] AS [ReadDt]
, [Extent1].[Reading] AS [Reading]
, [Extent1].[Units] AS [Units]
, [Extent1].[Transferred] AS [Transferred]
FROM
(SELECT
[ReadsToTransfer].[AMRID] AS [AMRID]
, [ReadsToTransfer].[Comments] AS [Comments]
, [ReadsToTransfer].[ExternalSystemType] AS [ExternalSystemType]
, [ReadsToTransfer].[LastReadDt] AS [LastReadDt]
, [ReadsToTransfer].[ReadDt] AS [ReadDt]
, [ReadsToTransfer].[Reading] AS [Reading]
, [ReadsToTransfer].[Transferred] AS [Transferred]
, [ReadsToTransfer].[Units] AS [Units]
FROM [dbo].[ReadsToTransfer] AS [ReadsToTransfer])
AS [Extent1]
Isso parece ser muito ineficiente, especialmente quando a tabela contém perto de 250 milhões de linhas como a nossa faz. Além disso, se eu alinhavar um .Pegue (2000) para o final do código, ele simplesmente coloca um 'select top 2000' apenas na primeira escolha. Assim, tornando-se selecionar o top 2000 do interior selecionar qual é a tabela inteira.
Quaisquer pensamentos sobre isso?
Solução
Isso parece ser muito ineficiente
Eu não penso assim ... SELECT exterior é apenas uma projeção (na verdade, uma projeção de identidade) do SELECT interna, e uma projeção tem um impacto no desempenho insignificante ...
No que se refere a cláusula TOP 2000, o fato de que é no SELECT exterior não significa que a DB irá ler todas as linhas da SELECT interna; ele vai lê-los enquanto eles são solicitados pelo SELECT exterior, em seguida, parar.
Basta tentar executar a consulta manualmente, com ou sem o SELECT externa: Aposto que você não vai encontrar nenhuma diferença significativa no desempenho
.