Entity Framework 连接多个表很慢
Entity Framework Join multiple tables is slow
我第一次尝试使用 Entity Framework 加入这么多 table。
一切正常,但加载时间大约为 1 分钟,非常糟糕。我不知道加入这么多 table 是否有不同的解决方案,或者有什么可以帮助的。
数据库中大约有5000条记录。我认为将来这个记录的数量可以更高。我需要一些可以接受的东西。谢谢
代码如下:
var JoinedTopCars = db.CustomerAdvertisement.Where(o => o.Top == true)
.Join(
db.CarManufacturerName,
n => n.CarManufacturerId,
q => q.CarManufacturerId,
(n, q) => new
{
n,
q,
})
.Join(
db.CarManufacturerModel,
o => o.n.CarModelId,
j => j.CarModelId,
(o, j) => new
{
j,
o,
}).Where(y => y.j.CarManufacturerId == y.o.q.CarManufacturerId)
.Join(
db.TypeOFFuel,
e => e.o.n.FuelId,
r => r.Id,
(e, r) => new
{
e,
r,
})
.Join(
db.TypeOFGearBox,
t => t.e.o.n.GearBoxId,
i => i.Id,
(t, i) => new
{
t,
i,
})
.Join(
db.Country,
y => y.t.e.o.n.CountryOfOrigin,
u => u.Id,
(y, u) => new
{
y,
u,
})
.Join(
db.TypeOFChassis,
c => c.y.t.e.o.n.ChassisId,
d => d.Id,
(c, d) => new
{
c,
d,
})
.Join(
db.CarDoors,
e => e.c.y.t.e.o.n.CarDoorsId,
f => f.Id,
(e, f) => new
{
e,
f,
})
.Join(
db.TypOfMovement,
g => g.e.c.y.t.e.o.n.MovementId,
f => f.Id,
(g, f) => new
{
g,
f,
})
.Join(
db.Area,
i => i.g.e.c.y.t.e.o.n.AreaOfOrigin ?? 0,
f => f.Id,
(i, f) => new
{
i,
f,
})
.Join(
db.District,
j => j.i.g.e.c.y.t.e.o.n.OkresOfOrigin ?? 0,
f => f.Id,
(j, f) => new
{
j,
f,
})
.Join(
db.CarColor,
k => k.j.i.g.e.c.y.t.e.o.n.CarColorId,
x => x.Id,
(k, x) => new JoinedTopCars
{
Id = k.j.i.g.e.c.y.t.e.o.n.Id,
Objem = k.j.i.g.e.c.y.t.e.o.n.cm3,
Carname = k.j.i.g.e.c.y.t.e.o.q.CarName,
CarModel = k.j.i.g.e.c.y.t.e.j.CarModel,
Typ = k.j.i.g.e.c.y.t.e.o.n.ModelType,
Color = x.ColorName,
Karoseria = k.j.i.g.e.d.ChassisName,
Dvere = k.j.i.g.f.NumberOfDoors,
Pohon = k.j.i.f.Movement,
VIN = k.j.i.g.e.c.y.t.e.o.n.VIN,
Metalic = k.j.i.g.e.c.y.t.e.o.n.Metalic,
Poskodene = k.j.i.g.e.c.y.t.e.o.n.Crashed,
Pojazdne = k.j.i.g.e.c.y.t.e.o.n.Drivable,
DPH = k.j.i.g.e.c.y.t.e.o.n.DPH,
Leasing = k.j.i.g.e.c.y.t.e.o.n.Leasing,
Emisie = k.j.i.g.e.c.y.t.e.o.n.Emmisions,
Spotreba = k.j.i.g.e.c.y.t.e.o.n.Consumption,
Km = k.j.i.g.e.c.y.t.e.o.n.KM,
Rok = k.j.i.g.e.c.y.t.e.o.n.DateOfOrigin.ToString(),
Vykon = k.j.i.g.e.c.y.t.e.o.n.HP,
Palivo = k.j.i.g.e.c.y.t.r.Fuel,
Prevodovka = k.j.i.g.e.c.y.i.GearBox,
Krajina = k.j.i.g.e.c.u.CountryName,
Okres = k.f.DistrictName,
Kraj = k.j.f.AreaName,
Vybava = k.j.i.g.e.c.y.t.e.o.n.Equipment,
Popis = k.j.i.g.e.c.y.t.e.o.n.Description,
Kontakt = k.j.i.g.e.c.y.t.e.o.n.ContInfo,
ZobrazMeno = k.j.i.g.e.c.y.t.e.o.n.ShowName,
ZobrazCislo = k.j.i.g.e.c.y.t.e.o.n.ShowPhone,
Cena = k.j.i.g.e.c.y.t.e.o.n.Price,
TitleImage = k.j.i.g.e.c.y.t.e.o.n.TitlePhoto,
})
.OrderByDescending(z => z.Id)
.Take(15);
编辑:我做了@romfir 写的下面的内容,并将加载时间从 1 分钟减少到 3 秒。
- 创建 SQL 视图
- 使用 JOINed tables 插入 SQL 查询(如果您希望空值使用 LEFT JOIN)
- 更新ADO.NET EF模型,.edmx文件
- 使用此 SQL 查看类似 table
你可以尝试在数据库中创建View,像这样:
CREATE VIEW my_view_name
AS
SELECT
CustomerAdvertisement.ID as CustomerAdvertisementID -- 'as Name' is optional
CustomerAdvertisement.cm3
-- other columns You want to include
FROM
CustomerAdvertisement
JOIN CarManufacturerName
on CarManufacturerName.CarManufacturerId = CustomerAdvertisement.CarManufacturerId
JOIN SomeTable
on some_condition
-- other joins
WHERE
CustomerAdvertisement.Top = true
and other_conditions
创建符合您的条件的视图后,您可以scaffold它,然后在您的代码中使用。
我第一次尝试使用 Entity Framework 加入这么多 table。
一切正常,但加载时间大约为 1 分钟,非常糟糕。我不知道加入这么多 table 是否有不同的解决方案,或者有什么可以帮助的。
数据库中大约有5000条记录。我认为将来这个记录的数量可以更高。我需要一些可以接受的东西。谢谢
代码如下:
var JoinedTopCars = db.CustomerAdvertisement.Where(o => o.Top == true)
.Join(
db.CarManufacturerName,
n => n.CarManufacturerId,
q => q.CarManufacturerId,
(n, q) => new
{
n,
q,
})
.Join(
db.CarManufacturerModel,
o => o.n.CarModelId,
j => j.CarModelId,
(o, j) => new
{
j,
o,
}).Where(y => y.j.CarManufacturerId == y.o.q.CarManufacturerId)
.Join(
db.TypeOFFuel,
e => e.o.n.FuelId,
r => r.Id,
(e, r) => new
{
e,
r,
})
.Join(
db.TypeOFGearBox,
t => t.e.o.n.GearBoxId,
i => i.Id,
(t, i) => new
{
t,
i,
})
.Join(
db.Country,
y => y.t.e.o.n.CountryOfOrigin,
u => u.Id,
(y, u) => new
{
y,
u,
})
.Join(
db.TypeOFChassis,
c => c.y.t.e.o.n.ChassisId,
d => d.Id,
(c, d) => new
{
c,
d,
})
.Join(
db.CarDoors,
e => e.c.y.t.e.o.n.CarDoorsId,
f => f.Id,
(e, f) => new
{
e,
f,
})
.Join(
db.TypOfMovement,
g => g.e.c.y.t.e.o.n.MovementId,
f => f.Id,
(g, f) => new
{
g,
f,
})
.Join(
db.Area,
i => i.g.e.c.y.t.e.o.n.AreaOfOrigin ?? 0,
f => f.Id,
(i, f) => new
{
i,
f,
})
.Join(
db.District,
j => j.i.g.e.c.y.t.e.o.n.OkresOfOrigin ?? 0,
f => f.Id,
(j, f) => new
{
j,
f,
})
.Join(
db.CarColor,
k => k.j.i.g.e.c.y.t.e.o.n.CarColorId,
x => x.Id,
(k, x) => new JoinedTopCars
{
Id = k.j.i.g.e.c.y.t.e.o.n.Id,
Objem = k.j.i.g.e.c.y.t.e.o.n.cm3,
Carname = k.j.i.g.e.c.y.t.e.o.q.CarName,
CarModel = k.j.i.g.e.c.y.t.e.j.CarModel,
Typ = k.j.i.g.e.c.y.t.e.o.n.ModelType,
Color = x.ColorName,
Karoseria = k.j.i.g.e.d.ChassisName,
Dvere = k.j.i.g.f.NumberOfDoors,
Pohon = k.j.i.f.Movement,
VIN = k.j.i.g.e.c.y.t.e.o.n.VIN,
Metalic = k.j.i.g.e.c.y.t.e.o.n.Metalic,
Poskodene = k.j.i.g.e.c.y.t.e.o.n.Crashed,
Pojazdne = k.j.i.g.e.c.y.t.e.o.n.Drivable,
DPH = k.j.i.g.e.c.y.t.e.o.n.DPH,
Leasing = k.j.i.g.e.c.y.t.e.o.n.Leasing,
Emisie = k.j.i.g.e.c.y.t.e.o.n.Emmisions,
Spotreba = k.j.i.g.e.c.y.t.e.o.n.Consumption,
Km = k.j.i.g.e.c.y.t.e.o.n.KM,
Rok = k.j.i.g.e.c.y.t.e.o.n.DateOfOrigin.ToString(),
Vykon = k.j.i.g.e.c.y.t.e.o.n.HP,
Palivo = k.j.i.g.e.c.y.t.r.Fuel,
Prevodovka = k.j.i.g.e.c.y.i.GearBox,
Krajina = k.j.i.g.e.c.u.CountryName,
Okres = k.f.DistrictName,
Kraj = k.j.f.AreaName,
Vybava = k.j.i.g.e.c.y.t.e.o.n.Equipment,
Popis = k.j.i.g.e.c.y.t.e.o.n.Description,
Kontakt = k.j.i.g.e.c.y.t.e.o.n.ContInfo,
ZobrazMeno = k.j.i.g.e.c.y.t.e.o.n.ShowName,
ZobrazCislo = k.j.i.g.e.c.y.t.e.o.n.ShowPhone,
Cena = k.j.i.g.e.c.y.t.e.o.n.Price,
TitleImage = k.j.i.g.e.c.y.t.e.o.n.TitlePhoto,
})
.OrderByDescending(z => z.Id)
.Take(15);
编辑:我做了@romfir 写的下面的内容,并将加载时间从 1 分钟减少到 3 秒。
- 创建 SQL 视图
- 使用 JOINed tables 插入 SQL 查询(如果您希望空值使用 LEFT JOIN)
- 更新ADO.NET EF模型,.edmx文件
- 使用此 SQL 查看类似 table
你可以尝试在数据库中创建View,像这样:
CREATE VIEW my_view_name
AS
SELECT
CustomerAdvertisement.ID as CustomerAdvertisementID -- 'as Name' is optional
CustomerAdvertisement.cm3
-- other columns You want to include
FROM
CustomerAdvertisement
JOIN CarManufacturerName
on CarManufacturerName.CarManufacturerId = CustomerAdvertisement.CarManufacturerId
JOIN SomeTable
on some_condition
-- other joins
WHERE
CustomerAdvertisement.Top = true
and other_conditions
创建符合您的条件的视图后,您可以scaffold它,然后在您的代码中使用。