使用实体框架最大化性能

时间:2015-12-17 15:51:49

标签: entity-framework linq-to-entities database-performance query-performance

我正在开发旅游网站。 当用户输入搜索位置(自动填充)时,我的操作会返回所有城市,城市地区,地区,地区翻译,酒店.....以用户输入开头

我首先使用了实体代码。但这是响应时间太多了。我该如何优化呢?我怎样才能减少时间?

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

1 个答案:

答案 0 :(得分:0)

如果没有看到生成的数据库架构或了解有关数据库引擎或服务器配置的任何信息,很难肯定地说最能提高查询性能的是什么。但是,检查代码时,我建议确保以下属性具有与之关联的索引:

  1. CityTranslations.Slug
  2. CityTranslations.Name
  3. RegionTranslations.Slug
  4. RegionTranslations.Name
  5. CityLandmarks.Name
  6. 这应该会立即提升,因为StartsWith应该以{{1​​}}的形式生成一个子句,因此索引应该会显着提高性能。

    LIKE 'xxx%'可能需要在某种程度上重新访问,因为Contains将生成一个HotelTranslations形式的子句,它不会从简单的索引中受益。

    如果这些字段上已有索引,请提供有关配置的其他信息(数据库,服务器配置,生成的架构等)。