问题描述
我正在开发旅游网站。当用户输入搜索位置(自动完成)时,我的操作将返回所有城市,城市地区,区域,地区翻译,酒店.....从用户输入开始
我首先使用了实体代码。但是响应时间太多了。如何优化?如何减少时间?
public JsonResult AutoComplateCityxxxxxxxx(string culture,string q)
{
列表<元组< string,int,int>> result = new List< Tuple< string,int,int>>();
using(var db = new TourismContext())
{
ModelState.Remove(q);
var query = SearchWordFunctions.WordFunctions(q);
var ListCity = db.CityTranslations.Where(
c =>(c.Slug.StartsWith(query)|| c.Name.StartsWith(query))
&
c.City.Latitude.HasValue
).GroupBy(x => x.CityID).Select(g => g.FirstOrDefault())Take(10 );
var ListRegion = db.RegionTranslations.Where(
r =>(r.Slug.StartsWith(query)|| r.Name.StartsWith(query))
& &
r.Region.Latitude.HasValue
&&
r.Region.RefID == 0&& r.Region.IsShow> 0
) .GroupBy(x => x.RegionID).Select(g => g.FirstOrDefault())。
var LandMark = db.CityLandMarks.Where(l => l.Translations.Any(t => t.Name.StartsWith(query))& amp; l.Latitude.HasValue) 。取(10);
var hotel = db.HotelTranslations.Where(t => t.Url.Contains(query)&& t.Hotel.Status> 0& ;& t.Culture.Code == culture).ToList();
result.Clear();
foreach(ListCity.OrderBy(o => o.Name.Length)中的var项)
{
result.Add(new Tuple< string, int,int>(string.Concat(item.Name, - < b>)item.City.Country.Translations.Single(t => t.CultureID == 1).Name,< b> ),item.CityID,1));
if(db.Regions.Any(r => r.CityID == item.CityID))
{
var regions = db.Regions.Where(r = > r.CityID == item.CityID&& r.Latitude.HasValue& r.RefID == 0&& rsIsShow> 0).GroupBy(g => g.ID ).Select(x => x.FirstOrDefault())。ToList()。OrderByDescending(o => o.SearchRating).Take(10);
foreach(var regItem in regions)
{
result.Add(new Tuple< string,int,int>(string.Concat(regItem.Translations.FirstOrDefault()名称, - < b>,item.Name,< / b> - < b>,regItem.City.Translations.FirstOrDefault()。Name,< b>),regItem .ID,2));
}
}
}
if(ListCity.Count()< = 0)
{
foreach(ListRegion中的var项)
{
result.Add(new Tuple< string,int,int>(string.Concat(item.Name, - < b>)item.Region.City.Translations.Single(t => t.Culture.Code == culture).Name,< / b> - < b>,item.Region.City.Country.Translations.Single(t => t.Culture.Code == culture) .Name,< / b>),item.RegionID,2));
}
}
foreach(LandMark中的var项)
{
result.Add(new Tuple< string,int,int>(string。 ()。名称, - < b> .Translations.FirstOrDefault()。Name,< / b>),item.ID,3));
}
foreach(酒店中的var项目)
{
result.Add(new Tuple< string,int,int>(string.Concat(item.Name , - < b class = \refid\data = \+ item.HotelID +\>,item.Hotel.Region.City.Translations.First() < / b>),item.Hotel.Region.CityID,1));
}
}
返回Json(result,JsonRequestBehavior.AllowGet);
}
或者知道有关数据库引擎或服务器配置的任何事情,很难说明什么会提高您的查询性能。但是,请查看您的代码,我建议确保以下属性具有与之相关联的索引:
-
CityTranslations。 Slug
-
CityTranslations.Name
-
RegionTranslations.Slug
-
RegionTranslations.Name
-
CityLandmarks.Name
这应该会立即提升,因为StartsWith应该生成一个表单 LIKE'xxx%'
的子句,所以索引应该显着提高性能。
HotelTranslations
可能需要在某种程度上重新访问,因为Contains将生成一个表单 LIKE'%xxx%'
的子句不能从简单的索引中获益。
如果这些字段上已经有索引,那么请提供有关您的配置的其他信息(DB,服务器配置,生成的模式等) )。
I am developing travel web site.When user input a location for search(autocomplete) my action return all cities, that cities regions, regions, regions translations, hotels..... which start with user input
I used Entity code first. But it is response time is too much. How can I optimize this? How can I decrease time?
public JsonResult AutoComplateCityxxxxxxxx(string culture, string q)
{
List<Tuple<string, int, int>> result = new List<Tuple<string, int, int>>();
using (var db = new TourismContext())
{
ModelState.Remove(q);
var query = SearchWordFunctions.WordFunctions(q);
var ListCity = db.CityTranslations.Where(
c => (c.Slug.StartsWith(query) || c.Name.StartsWith(query))
&&
c.City.Latitude.HasValue
).GroupBy(x => x.CityID).Select(g => g.FirstOrDefault()).Take(10);
var ListRegion = db.RegionTranslations.Where(
r => (r.Slug.StartsWith(query) || r.Name.StartsWith(query))
&&
r.Region.Latitude.HasValue
&&
r.Region.RefID == 0 && r.Region.IsShow > 0
).GroupBy(x => x.RegionID).Select(g => g.FirstOrDefault()).Take(10);
var LandMark = db.CityLandMarks.Where(l => l.Translations.Any(t => t.Name.StartsWith(query)) && l.Latitude.HasValue).Take(10);
var hotel = db.HotelTranslations.Where(t => t.Url.Contains(query) && t.Hotel.Status > 0 && t.Culture.Code == culture).ToList();
result.Clear();
foreach (var item in ListCity.OrderBy(o => o.Name.Length))
{
result.Add(new Tuple<string, int, int>(string.Concat(item.Name, " - <b>", item.City.Country.Translations.Single(t => t.CultureID == 1).Name, "<b>"), item.CityID, 1));
if (db.Regions.Any(r => r.CityID == item.CityID))
{
var regions = db.Regions.Where(r => r.CityID == item.CityID && r.Latitude.HasValue && r.RefID == 0 && r.IsShow > 0).GroupBy(g => g.ID).Select(x => x.FirstOrDefault()).ToList().OrderByDescending(o => o.SearchRating).Take(10);
foreach (var regItem in regions)
{
result.Add(new Tuple<string, int, int>(string.Concat(regItem.Translations.FirstOrDefault().Name, " - <b>", item.Name, "</b> - <b>", regItem.City.Country.Translations.FirstOrDefault().Name, "<b>"), regItem.ID, 2));
}
}
}
if (ListCity.Count() <= 0)
{
foreach (var item in ListRegion)
{
result.Add(new Tuple<string, int, int>(string.Concat(item.Name, " - <b>", item.Region.City.Translations.Single(t => t.Culture.Code == culture).Name, "</b> - <b>", item.Region.City.Country.Translations.Single(t => t.Culture.Code == culture).Name, "</b>"), item.RegionID, 2));
}
}
foreach (var item in LandMark)
{
result.Add(new Tuple<string, int, int>(string.Concat(item.Translations.FirstOrDefault().Name, " - <b>", item.City.Translations.FirstOrDefault().Name, "</b> - <b>", item.City.Country.Translations.FirstOrDefault().Name, "</b>"), item.ID, 3));
}
foreach (var item in hotel)
{
result.Add(new Tuple<string, int, int>(string.Concat(item.Name, " - <b class=\"refid\" data=\"" + item.HotelID + "\">", item.Hotel.Region.City.Translations.First().Name, "</b>"), item.Hotel.Region.CityID, 1));
}
}
return Json(result, JsonRequestBehavior.AllowGet);
}
Without seeing your generated DB schema or knowing anything about the DB engine or server configuration, it is difficult to say with any certainty what will improve your query performance the most. Reviewing your code, though, I would recommend ensuring that the following attributes have indexes associated with them:
CityTranslations.Slug
CityTranslations.Name
RegionTranslations.Slug
RegionTranslations.Name
CityLandmarks.Name
That should give you an immediate boost, since StartsWith should generate a clause in the form LIKE 'xxx%'
, so an index should significantly improve performance.
HotelTranslations
may need to be revisited to some extent, since Contains will generate a clause of the form LIKE '%xxx%'
which will not benefit from a simple index.
If there are already indexes on those fields, then please provide additional information about your configuration (DB, server config, generated schema, etc).
这篇关于实体框架最大化性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!