1
efクエリを最適化しようとするときに問題があります。私は生成されたSQLでもエンティティ構文にマッピングすることを言及していないにもかかわらず、何が変わるのか分かりません。どのような最適化のヒントにも大変感謝しています。 EFの問合せ:PostGresqlのEFから生成されたクエリで最適でないカウント
var data = Context.Premise.Where(p => p.TransportManager != null);
var query = from premise in data
join psi in Context.PremiseSeriousInfringement on premise.Id equals psi.PremiseId
group psi by psi.Premise into bp
let types = from type in bp
select type.SeriousInfringement.SeriousInfringementCode.SeriousInfringementType.Value
let premise = bp.Key
let NNInfringementCount = types.Count(t => t == "NN")
let BPNInfringementCount = types.Count(t => t == "BPN")
let PNInfringementCount = types.Count(t => t == "PN")
select new
{
NNInfringementCount,
BPNInfringementCount,
PNInfringementCount,
premise.Id,
premise.Type,
premise.Status,
premise.CreationDate,
premise.BusinessCaseNumber,
FirstNames = premise.TransportManager.FirstNames,
FamilyName = premise.TransportManager.FamilyName,
CertificateNumber = premise.TransportManager.CertificateNumber,
Types = types
};
query = query.OrderBy(filter.sortField + " " + filter.sortOrder)
.Skip((filter.pageIndex - 1) * filter.pageSize)
.Take(filter.pageSize);
これは、それが生成するクエリである[私はそれがより読みやすくなりましたEDIT]:
SELECT "Project8"."UndertakingId", "Project8"."TransportManagerId", "Project8"."CancelReasons", "Project8"."WarningDate", "Project8"."WarningDeliveryDate", "Project8"."FinishDate", "Project8"."InternalProceeding", "Project8"."AuthorityId", "Project8"."PenaltyImposed", "Project8"."PenaltyDescription", "Project8"."PenaltyType", "Project8"."isSendToEpuap", "Project8"."ModificationDate", "Project8"."CreatedByAppUserId", "Project8"."LastModifiedByAppUserId", "Project8"."Id1" AS "Id", "Project8"."Id" AS "Id1", "Project8"."C2" AS "C1", "Project8"."C3" AS "C2", "Project8"."C4" AS "C3", "Project8"."Type", "Project8"."Status", "Project8"."CreationDate", "Project8"."BusinessCaseNumber", "Project8"."FirstNames", "Project8"."FamilyName", "Project8"."CertificateNumber", "Project8"."C1" AS "C4", "Project8"."Value" FROM (
SELECT "Join14"."Id", "Join14"."UndertakingId", "Join14"."TransportManagerId", "Join14"."Type", "Join14"."Status", "Join14"."CancelReasons", "Join14"."WarningDate", "Join14"."WarningDeliveryDate", "Join14"."FinishDate", "Join14"."InternalProceeding", "Join14"."AuthorityId", "Join14"."PenaltyImposed", "Join14"."PenaltyDescription", "Join14"."BusinessCaseNumber", "Join14"."PenaltyType", "Join14"."isSendToEpuap", "Join14"."CreationDate", "Join14"."ModificationDate", "Join14"."CreatedByAppUserId", "Join14"."LastModifiedByAppUserId", "Join14"."Id_Alias12" AS "Id1", "Join14"."CertificateNumber", "Join14"."FirstNames", "Join14"."FamilyName", "Join18"."Value", CASE WHEN ("Join18"."SeriousInfringementId" IS NULL) THEN (CAST (NULL AS int4)) ELSE (1) END AS "C1", "Join14"."C1" AS "C2", "Join14"."C2" AS "C3", "Join14"."C3" AS "C4" FROM (
SELECT "Project7"."Id", "Project7"."UndertakingId", "Project7"."TransportManagerId", "Project7"."Type", "Project7"."Status", "Project7"."CancelReasons", "Project7"."WarningDate", "Project7"."WarningDeliveryDate", "Project7"."FinishDate", "Project7"."InternalProceeding", "Project7"."AuthorityId", "Project7"."PenaltyImposed", "Project7"."PenaltyDescription", "Project7"."BusinessCaseNumber", "Project7"."PenaltyType", "Project7"."isSendToEpuap", "Project7"."CreationDate", "Project7"."ModificationDate", "Project7"."CreatedByAppUserId", "Project7"."LastModifiedByAppUserId", "Extent18"."Id" AS "Id_Alias12", "Extent18"."CertificateNumber", "Extent18"."FirstNames", "Extent18"."FamilyName", "Project7"."C1", "Project7"."C2", "Project7"."C3" FROM (
SELECT "Project5"."Id", "Project5"."UndertakingId", "Project5"."TransportManagerId", "Project5"."Type", "Project5"."Status", "Project5"."CancelReasons", "Project5"."WarningDate", "Project5"."WarningDeliveryDate", "Project5"."FinishDate", "Project5"."InternalProceeding", "Project5"."AuthorityId", "Project5"."PenaltyImposed", "Project5"."PenaltyDescription", "Project5"."BusinessCaseNumber", "Project5"."PenaltyType", "Project5"."isSendToEpuap", "Project5"."CreationDate", "Project5"."ModificationDate", "Project5"."CreatedByAppUserId", "Project5"."LastModifiedByAppUserId", "Project5"."C1", "Project5"."C2", (
SELECT CAST (count(1) AS int4) AS "A1" FROM (
SELECT "Join12"."SeriousInfringementId", "Join12"."Id_Alias10" AS "Id", "Join12"."SeriousInfringementCodeId", "Join12"."Id_Alias11" AS "Id1", "Join12"."SeriousInfringementTypeId", "Extent17"."Id" AS "Id2", "Extent17"."Value" FROM (
SELECT "Extent16"."SeriousInfringementTypeId", "Extent13"."Id", "Extent14"."SeriousInfringementId", "Extent15"."Id" AS "Id_Alias10", "Extent15"."SeriousInfringementCodeId", "Extent16"."Id" AS "Id_Alias11" FROM "dbo"."Premise" AS "Extent13"
INNER JOIN "dbo"."PremiseSeriousInfringement" AS "Extent14" ON "Extent13"."Id" = "Extent14"."PremiseId"
INNER JOIN "dbo"."SeriousInfringement" AS "Extent15" ON "Extent14"."SeriousInfringementId" = "Extent15"."Id"
INNER JOIN "dbo"."SeriousInfringementCode" AS "Extent16" ON "Extent15"."SeriousInfringementCodeId" = "Extent16"."Id" WHERE "Extent13"."TransportManagerId" IS NOT NULL) AS "Join12"
INNER JOIN "dbo"."DictionaryValue" AS "Extent17" ON "Join12"."SeriousInfringementTypeId" = "Extent17"."Id" WHERE ("Project5"."Id" = "Join12"."Id" OR TRUE = FALSE) AND E'PN' = "Extent17"."Value") AS "Project6") AS "C3" FROM (
SELECT "Project3"."Id", "Project3"."UndertakingId", "Project3"."TransportManagerId", "Project3"."Type", "Project3"."Status", "Project3"."CancelReasons", "Project3"."WarningDate", "Project3"."WarningDeliveryDate", "Project3"."FinishDate", "Project3"."InternalProceeding", "Project3"."AuthorityId", "Project3"."PenaltyImposed", "Project3"."PenaltyDescription", "Project3"."BusinessCaseNumber", "Project3"."PenaltyType", "Project3"."isSendToEpuap", "Project3"."CreationDate", "Project3"."ModificationDate", "Project3"."CreatedByAppUserId", "Project3"."LastModifiedByAppUserId", "Project3"."C1", (
SELECT CAST (count(1) AS int4) AS "A1" FROM (
SELECT "Join8"."SeriousInfringementId", "Join8"."Id_Alias7" AS "Id", "Join8"."SeriousInfringementCodeId", "Join8"."Id_Alias8" AS "Id1", "Join8"."SeriousInfringementTypeId", "Extent12"."Id" AS "Id2", "Extent12"."Value" FROM (
SELECT "Extent11"."SeriousInfringementTypeId", "Extent8"."Id", "Extent9"."SeriousInfringementId", "Extent10"."Id" AS "Id_Alias7", "Extent10"."SeriousInfringementCodeId", "Extent11"."Id" AS "Id_Alias8" FROM "dbo"."Premise" AS "Extent8"
INNER JOIN "dbo"."PremiseSeriousInfringement" AS "Extent9" ON "Extent8"."Id" = "Extent9"."PremiseId"
INNER JOIN "dbo"."SeriousInfringement" AS "Extent10" ON "Extent9"."SeriousInfringementId" = "Extent10"."Id"
INNER JOIN "dbo"."SeriousInfringementCode" AS "Extent11" ON "Extent10"."SeriousInfringementCodeId" = "Extent11"."Id" WHERE "Extent8"."TransportManagerId" IS NOT NULL) AS "Join8"
INNER JOIN "dbo"."DictionaryValue" AS "Extent12" ON "Join8"."SeriousInfringementTypeId" = "Extent12"."Id" WHERE ("Project3"."Id" = "Join8"."Id" OR TRUE = FALSE) AND E'BPN' = "Extent12"."Value") AS "Project4") AS "C2" FROM (
SELECT "Alias2"."Id", "Alias2"."UndertakingId", "Alias2"."TransportManagerId", "Alias2"."Type", "Alias2"."Status", "Alias2"."CancelReasons", "Alias2"."WarningDate", "Alias2"."WarningDeliveryDate", "Alias2"."FinishDate", "Alias2"."InternalProceeding", "Alias2"."AuthorityId", "Alias2"."PenaltyImposed", "Alias2"."PenaltyDescription", "Alias2"."BusinessCaseNumber", "Alias2"."PenaltyType", "Alias2"."isSendToEpuap", "Alias2"."CreationDate", "Alias2"."ModificationDate", "Alias2"."CreatedByAppUserId", "Alias2"."LastModifiedByAppUserId", (
SELECT CAST (count(1) AS int4) AS "A1" FROM (
SELECT "Join4"."SeriousInfringementId", "Join4"."Id_Alias4" AS "Id", "Join4"."SeriousInfringementCodeId", "Join4"."Id_Alias5" AS "Id1", "Join4"."SeriousInfringementTypeId", "Extent7"."Id" AS "Id2", "Extent7"."Value" FROM (
SELECT "Extent6"."SeriousInfringementTypeId", "Extent3"."Id", "Extent4"."SeriousInfringementId", "Extent5"."Id" AS "Id_Alias4", "Extent5"."SeriousInfringementCodeId", "Extent6"."Id" AS "Id_Alias5" FROM "dbo"."Premise" AS "Extent3"
INNER JOIN "dbo"."PremiseSeriousInfringement" AS "Extent4" ON "Extent3"."Id" = "Extent4"."PremiseId"
INNER JOIN "dbo"."SeriousInfringement" AS "Extent5" ON "Extent4"."SeriousInfringementId" = "Extent5"."Id"
INNER JOIN "dbo"."SeriousInfringementCode" AS "Extent6" ON "Extent5"."SeriousInfringementCodeId" = "Extent6"."Id" WHERE "Extent3"."TransportManagerId" IS NOT NULL) AS "Join4"
INNER JOIN "dbo"."DictionaryValue" AS "Extent7" ON "Join4"."SeriousInfringementTypeId" = "Extent7"."Id" WHERE ("Alias2"."Id" = "Join4"."Id" OR TRUE = FALSE) AND E'NN' = "Extent7"."Value") AS "Project2") AS "C1" FROM (
SELECT DISTINCT "Extent1"."Id", "Extent1"."UndertakingId", "Extent1"."TransportManagerId", "Extent1"."Type", "Extent1"."Status", "Extent1"."CancelReasons", "Extent1"."WarningDate", "Extent1"."WarningDeliveryDate", "Extent1"."FinishDate", "Extent1"."InternalProceeding", "Extent1"."AuthorityId", "Extent1"."PenaltyImposed", "Extent1"."PenaltyDescription", "Extent1"."BusinessCaseNumber", "Extent1"."PenaltyType", "Extent1"."isSendToEpuap", "Extent1"."CreationDate", "Extent1"."ModificationDate", "Extent1"."CreatedByAppUserId", "Extent1"."LastModifiedByAppUserId" FROM "dbo"."Premise" AS "Extent1"
INNER JOIN "dbo"."PremiseSeriousInfringement" AS "Extent2" ON "Extent1"."Id" = "Extent2"."PremiseId" AND "Extent2"."PremiseId" = "Extent1"."Id" WHERE "Extent1"."TransportManagerId" IS NOT NULL) AS "Alias2") AS "Project3") AS "Project5") AS "Project7"
LEFT OUTER JOIN "dbo"."TransportManager" AS "Extent18" ON "Project7"."TransportManagerId" = "Extent18"."Id" ORDER BY "Project7"."Type" ASC OFFSET 0 LIMIT 25) AS "Join14"
LEFT OUTER JOIN (
SELECT "Extent19"."Id", "Extent23"."Value", "Extent20"."SeriousInfringementId" FROM "dbo"."Premise" AS "Extent19"
INNER JOIN "dbo"."PremiseSeriousInfringement" AS "Extent20" ON "Extent19"."Id" = "Extent20"."PremiseId"
INNER JOIN "dbo"."SeriousInfringement" AS "Extent21" ON "Extent20"."SeriousInfringementId" = "Extent21"."Id"
INNER JOIN "dbo"."SeriousInfringementCode" AS "Extent22" ON "Extent21"."SeriousInfringementCodeId" = "Extent22"."Id"
INNER JOIN "dbo"."DictionaryValue" AS "Extent23" ON "Extent22"."SeriousInfringementTypeId" = "Extent23"."Id" WHERE "Extent19"."TransportManagerId" IS NOT NULL) AS "Join18" ON "Join14"."Id" = "Join18"."Id" OR TRUE = FALSE) AS "Project8" ORDER BY "Project8"."Type" ASC ,"Project8"."UndertakingId" ASC ,"Project8"."TransportManagerId" ASC ,"Project8"."CancelReasons" ASC ,"Project8"."WarningDate" ASC ,"Project8"."WarningDeliveryDate" ASC ,"Project8"."FinishDate" ASC ,"Project8"."InternalProceeding" ASC ,"Project8"."AuthorityId" ASC ,"Project8"."PenaltyImposed" ASC ,"Project8"."PenaltyDescription" ASC ,"Project8"."PenaltyType" ASC ,"Project8"."isSendToEpuap" ASC ,"Project8"."ModificationDate" ASC ,"Project8"."CreatedByAppUserId" ASC ,"Project8"."LastModifiedByAppUserId" ASC ,"Project8"."Id1" ASC ,"Project8"."Id" ASC ,"Project8"."Status" ASC ,"Project8"."CreationDate" ASC ,"Project8"."BusinessCaseNumber" ASC ,"Project8"."C1" ASC
これはpgAdminでIIIによって提案された計画である:
[編集]私の友人は、そのようなSQLを来た:
select premise."Id", premise."Type", premise."CreationDate", premise."Status", premise."BusinessCaseNumber", tm."FirstNames", tm."FamilyName",tm."CertificateNumber",premiseSum.NNCount, premiseSum.BPNCount, premiseSum.PNCount from
(
select distinct
premiseGroup."PremiseId",
sum(premiseGroup.NNCount) OVER (partition BY premiseGroup."PremiseId") NNCount,
sum(premiseGroup.BPNCount) OVER (partition BY premiseGroup."PremiseId") BPNCount,
sum(premiseGroup.PNCount) OVER (partition BY premiseGroup."PremiseId") PNCount
from
(
select psi."PremiseId",
(select sum(count(sit."Value")) OVER (ORDER BY psi."PremiseId") where "Value" = 'NN') NNCount,
(select sum(count(sit."Value")) OVER (ORDER BY psi."PremiseId") where "Value" = 'PN') PNCount,
(select sum(count(sit."Value")) OVER (ORDER BY psi."PremiseId") where "Value" = 'BPN') BPNCount
from "dbo"."Premise" premise
inner join "dbo"."PremiseSeriousInfringement" psi on psi."PremiseId" = premise."Id"
inner join "dbo"."SeriousInfringement" si on psi."SeriousInfringementId" = si."Id"
inner join "dbo"."SeriousInfringementCode" sic on si."SeriousInfringementCodeId" = sic."Id"
inner join "dbo"."DictionaryValue" sit on sic."SeriousInfringementTypeId" = sit."Id"
group by psi."PremiseId", sit."Value"
) premiseGroup
) premiseSum
join "dbo"."Premise" premise on premise."Id" = premiseSum."PremiseId"
join "dbo"."TransportManager" tm on tm."Id" = premise."TransportManagerId"
これは本当に高速で素敵なクエリプランですが、LINQとEFでこれを書く方法はわかりません。
これは高速ですが、あまり変更されていないため、EFはネストされたループを持つ3つのサブクエリを作成します。 –