Структура сущности:запрос, выполняющий «выбрать из» без причины
-
19-09-2019 - |
Вопрос
У меня возникли некоторые проблемы с инфраструктурой сущности.Я выполняю простой выбор из представления в базе данных.Однако, когда я просматриваю SQL, который генерирует EF, он выполняет запрос дважды, используя выбор из.Так ли это должно работать?Это кажется очень неэффективным.
var reads = (from rt in ctx.C2kReadsToTransfer
where rt.ReadDt > fromDate
&& rt.ReadDt < toDate
select rt);
Это преобразуется в следующий 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]
Это кажется очень неэффективным, особенно когда таблица содержит около 250 миллионов строк, как наша.Кроме того, если я добавлю .Take(2000) в конец кода, он просто поставит «выбрать топ 2000» только на первый выбор.Таким образом, он выбирает 2000 лучших из внутреннего выбора, который представляет собой всю таблицу.
Есть мысли по этому поводу?
Решение
Кажется, это очень неэффективно
Я так не думаю...внешний SELECT — это просто проекция (на самом деле проекция идентичности) внутреннего SELECT, и проекция оказывает незначительное влияние на производительность...
Что касается предложения TOP 2000, тот факт, что оно находится во внешнем SELECT, не означает, что БД будет читать все строки из внутреннего SELECT;он будет читать их до тех пор, пока они запрашиваются внешним SELECT, а затем остановится.
Просто попробуйте запустить запрос вручную, с внешним SELECT или без него:Могу поспорить, что вы не обнаружите существенной разницы в производительности.