對於一個項目,我們不得不使用現有的表與實體框架。這解決了1大LINQ查詢的搜索功能。目前這個功能需要3秒鐘才能得到10個結果。Linq查詢頭疼
問題是,如果有人知道要改善這個linq的要點?
這是LINQ查詢:
var result = (from o in db.Objects
join omsc in db.Omschrijvingen on o.Omschrijving_Identifier equals omsc.Identifier
join a in db.Adressen on o.Adres_Id equals a.Adres_Id
join oa in db.Object_Abonnement on o.Object_Id equals oa.Object_ID
join oaf in db.Object_Afbeeldingen on o.Object_Id equals oaf.Object_Id
where o.Enabled && oaf.StandaardAfbeelding == true &&
(!iType.Any() || iType.Contains(o.Type_Id)) &&
(iProvince < 1 || a.Provincie_Id == iProvince) &&
(iDepartement < 1 || a.Departement_Id == iDepartement) &&
o.Object_Logs.All(
ol => ol.Log_Type != (int) ApplicationDefinitions.LogTypes.Deleted) &&
(oa.Betaald && oa.Tot >= DateTime.Now) &&
(!kenmerken.Any() ||
db.Object_Kenmerken.Count(
ken =>
kenmerken.Contains(ken.Kenmerk_Id) && ken.Object_Id == o.Object_Id &&
ken.Waarde.ToUpper() != "FALSE" && ken.Waarde != "0") == kenmerken.Count()) &&
(search.Length < 1 || omsc.Naam.ToLower().Contains(search.ToLower()) ||
omsc.Omschrijving.ToLower().Contains(search.ToLower()) ||
a.Woonplaats.ToLower().Contains(search.ToLower()))
select new FullObject
{
Object_Id = o.Object_Id,
Adres_Id = a.Adres_Id,
DepartmentId = a.Departement_Id,
Department = (a.Departementen != null) ? a.Departementen.Naam : "",
ProviciesId = a.Provincie_Id,
Provicie = (a.Provicies != null) ? a.Provicies.Naam : "",
Contact_Id = o.Contact_Id,
Naam = omsc.Naam,
Omschrijving = omsc.Omschrijving,
Prijs =
(((db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).Min(
pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).
Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).
Min(pp => pp.Prijs_Week)) > 0)
? (db.Prijs_Periode.Where(pp => pp.Object_Id == o.Object_Id).
Min
(pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Week/7)
: (db.Prijs_Periode
.Where(pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Weekend) > 0)
? db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Weekend/3)
: (db.Prijs_Periode
.Where(
pp => pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Midweek) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Midweek/14)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id)
.Min(pp => pp.Prijs_Langweekend) >
0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id)
.Min(
pp =>
pp.Prijs_Langweekend)
: 0,
SPrijs = (((db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Week)) > 0)
? (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Dag)
: db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Week/7)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Weekend) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Weekend/3)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Midweek) > 0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Midweek/14)
: (db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(pp => pp.Prijs_Langweekend) >
0)
? db.Prijs_Periode
.Where(
pp =>
pp.Object_Id == o.Object_Id &&
pp.Aanbieding == false)
.Min(
pp =>
pp.Prijs_Langweekend)
: 0,
Personen =
(db.Object_Kenmerken.Any(
iok =>
iok.Kenmerk_Id == iAantalPersonenId &&
iok.Object_Id == o.Object_Id))
? db.Object_Kenmerken.Where(
iok =>
iok.Kenmerk_Id == iAantalPersonenId &&
iok.Object_Id == o.Object_Id).Select(
iok => EntitiesFunctions.ParseInt(iok.Waarde)).
FirstOrDefault()
: 0,
Slaapkamers =
(db.Object_Kenmerken.Any(
iok =>
iok.Kenmerk_Id == iAantalSlaapkamersId &&
iok.Object_Id == o.Object_Id))
? db.Object_Kenmerken.Where(
iok =>
iok.Kenmerk_Id == iAantalSlaapkamersId &&
iok.Object_Id == o.Object_Id).Select(
iok => EntitiesFunctions.ParseInt(iok.Waarde)).
FirstOrDefault()
: 0,
UrlKey = omsc.UrlKey,
Title = omsc.Title,
Plaats = a.Woonplaats,
Enabled = o.Enabled,
GoogleMap_Url = o.GoogleMap_Url,
InkoopPrijs = o.InkoopPrijs,
Type_Id = o.Type_Id,
Website = o.Website,
Adressen = o.Adressen,
Thumb = oaf.Tumbnial
}
)
.Where(item => (item.Prijs >= minPrice || minPrice == 0) &&
(item.Prijs <= maxPrice || maxPrice == 0) &&
(bOffersOnly == false || item.Prijs < item.SPrijs) &&
(item.Personen >= personen || personen == 0) &&
(item.Slaapkamers == slaapkamers || slaapkamers == 0))
.Distinct();
爲了更清楚:
我們需要得到以下對象:
public class FullObject
{
public int Object_Id { get; set; }
public int? Adres_Id { get; set; }
public int Contact_Id { get; set; }
public string Naam { get; set; }
public string Omschrijving { get; set; }
public decimal? Prijs { get; set; }
public decimal? SPrijs { get; set; }
public int Personen { get; set; }
public int Slaapkamers { get; set; }
public string UrlKey { get; set; }
public string Title { get; set; }
public string Plaats { get; set; }
public int ProviciesId { get; set; }
public string Provicie { get; set; }
public int? DepartmentId { get; set; }
public string Department { get; set; }
public bool Enabled { get; set; }
public string GoogleMap_Url { get; set; }
public decimal? InkoopPrijs { get; set; }
public int Type_Id { get; set; }
public string Website { get; set; }
public List<Data.Object_Kenmerken> ItemKenmerken { get; set; }
public Data.Adressen Adressen { get; set; }
public string Thumb { get; set; }
}
我們必須對以下過濾器東西
int[] iType
string search
int[] kenmerken
int iProvince
int iDepartement
decimal minPrice
decimal maxPrice
int personen
int slaapkamers
bool bOffersOnly
這是(一點點)的表結構:
http://i.stack.imgur.com/3Y0Tf.jpg
我們試圖分別得到一切,但後來我們一共12秒(和增長)得到,因爲許多對象那是在數據庫中,然後我們需要通過過濾來獲取它們。
我希望有人認爲這是一個挑戰,看到我忽視的東西。
在此先感謝。
克里斯蒂安
由於此單被關閉,我的回答:
感謝所有的答覆。
最好的是@ Daniel-Hilgarth。不要在查詢中進行計算。爲了解決這個問題,我們選擇在每15分鐘運行一次的SQL作業中進行計算,並將結果直接放入Object表中。
接下來,我們已經改變了一點點連接到數據庫邏輯。感謝@ Micheal-Samteladze。
所有這些變化給了我們以下查詢。
var result = (from o in db.Objects
join omsc in db.Omschrijvingen on o.Omschrijving_Identifier equals omsc.Identifier
where o.Enabled &&
(!iType.Any() || iType.Contains(o.Type_Id)) &&
(o.Prijs >= minPrice || minPrice == 0) &&
(o.Prijs <= maxPrice || maxPrice == 0) &&
(bOffersOnly == false || o.Prijs < o.SPrijs) &&
(o.Personen >= personen || personen == 0) &&
(o.Kamers == slaapkamers || slaapkamers == 0) &&
(iProvince < 1 || o.Adressen.Provincie_Id == iProvince) &&
(iDepartement < 1 || o.Adressen.Departement_Id == iDepartement) &&
o.Object_Logs.All(ol => ol.Log_Type != (int) ApplicationDefinitions.LogTypes.Deleted) &&
o.Object_Abonnement.Any(oa => oa.Betaald && oa.Tot >= DateTime.Now) &&
(!kenmerken.Any() || o.Object_Kenmerken.Count(ken => kenmerken.Contains(ken.Kenmerk_Id) && ken.Object_Id == o.Object_Id && ken.Waarde.ToUpper() != "FALSE" && ken.Waarde != "0") == kenmerken.Count()) &&
(search.Length < 1 || omsc.Naam.ToLower().Contains(search.ToLower()) || omsc.Omschrijving.ToLower().Contains(search.ToLower()) || o.Adressen.Woonplaats.ToLower().Contains(search.ToLower()))
select new FullObject
{
Object_Id = o.Object_Id,
Adres_Id = o.Adressen.Adres_Id,
DepartmentId = o.Adressen.Departement_Id,
Department = (o.Adressen.Departementen != null) ? o.Adressen.Departementen.Naam : "",
ProviciesId = o.Adressen.Provincie_Id,
Provicie = (o.Adressen.Provicies != null) ? o.Adressen.Provicies.Naam : "",
Contact_Id = o.Contact_Id,
Naam = omsc.Naam,
Omschrijving = omsc.Omschrijving,
Prijs = o.Prijs ?? 0,
SPrijs = o.SPrijs ?? 0,
Personen = o.Personen,
Slaapkamers = 0,
UrlKey = omsc.UrlKey,
Title = omsc.Title,
Plaats = o.Adressen.Woonplaats,
Enabled = o.Enabled,
GoogleMap_Url = o.GoogleMap_Url,
InkoopPrijs = o.InkoopPrijs,
Type_Id = o.Type_Id,
Website = o.Website,
Adressen = o.Adressen,
Thumb = o.Object_Afbeeldingen.FirstOrDefault(af => af.StandaardAfbeelding).Tumbnial
}
)
.Distinct();
這大約需要1個半第二,得到第10的結果,其中舊土氣最低的3
但我仍然開放的建議。
感謝
克里斯蒂安
聖。 生活。 CRAP! –
是的,當我需要這樣的速度時,這也是我的反應。 –
我們在這裏沒有什麼可以做的。問題是這個查詢只是試圖做太多。但是,如果不知道實際應該做什麼,就很難優化它。 **老實說,這個查詢是一個很大的失敗。**它是無法維持到極致的。然而,有一件事:在那裏有許多令人難以置信的子查詢,我想知道是否有意義地完全獲取這些表並在內存中執行一些這些操作。 –