实体框架最大化性能 [英] Maximizing Performance with the Entity Framework

查看:110
本文介绍了实体框架最大化性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发旅游网站。
当用户输入搜索位置(自动完成)时,我的操作将返回所有城市,城市地区,区域,地区翻译,酒店.....从用户输入开始



我首先使用了实体代码。但是响应时间太多了。如何优化?如何减少时间?

  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);
}


解决方案

或者知道有关数据库引擎或服务器配置的任何事情,很难说明什么会提高您的查询性能。但是,请查看您的代码,我建议确保以下属性具有与之相关联的索引:


  1. CityTranslations。 Slug

  2. CityTranslations.Name

  3. RegionTranslations.Slug

  4. RegionTranslations.Name

  5. 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:

  1. CityTranslations.Slug
  2. CityTranslations.Name
  3. RegionTranslations.Slug
  4. RegionTranslations.Name
  5. 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).

这篇关于实体框架最大化性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆