【问题标题】:Improve Performance .net core 2.1 web api提高性能 .net core 2.1 web api
【发布时间】:2019-05-09 12:24:32
【问题描述】:

我创建了房地产网站,我的后端是 .net core 2.1,前端是 angular 7。对于 DB,我使用的是 sql server,现在我的数据库中有 1568 个数据(建筑物信息)。我的后端有性能问题,当我从 db 搜索数据时,显示数据需要 30 多秒。我阅读了许多有关在 sql server 中建立索引的信息,并在我的数据库中创建了非聚集索引,但是当我在 sql server 中进行测试时,它不使用我创建的索引。我如何提高后端的性能是我的搜索代码:

[HttpPost]
        [AllowAnonymous]
        public IActionResult Search([FromBody] SearchModel model)
        {    try
            { var query = _service.AllAsQueryable;

                if (model != null)
                {
                    if (!string.IsNullOrEmpty(model.Keyword))
                    { 


                        var keyword = model.Keyword.ToLower();
                        query = query.Where(a => a.BuildTitle.ToLower().Contains(keyword) ||
                                                 a.Description.ToLower().Contains(keyword) ||
                                                 a.ZipCode.ToLower().Contains(keyword) ||
                                                // (a.Country != null && a.Country.Localizations.Any(b => b.Name.ToLower().Contains(keyword))) ||
                                                 (a.Region != null && a.Region.Localizations.Any(b => b.Name.ToLower().Contains(keyword))) ||
                                                 (a.District != null && a.District.Localizations.Any(b => b.Name.ToLower().Contains(keyword))) ||
                                                 (a.Zone != null && a.Zone.Localizations.Any(b => b.Name.ToLower().Contains(keyword))));


                    }

                    if (model.RegionId.HasValue && model.RegionId > 0)
                        query = query.Where(a => a.RegionId == model.RegionId);

                    if (model.DistrictId.HasValue && model.DistrictId > 0)
                        query = query.Where(a => a.DistrictId == model.DistrictId);

                    if (model.ZoneId.HasValue && model.ZoneId > 0)
                        query = query.Where(a => a.ZoneId == model.ZoneId);

                    if (model.ClientTypeId.HasValue && model.ClientTypeId > 0)
                        query = query.Where(a => a.ClientTypeId == model.ClientTypeId);

                    if (model.PriceFrom.HasValue)
                        query = query.Where(a => a.OwnerPrice >= model.PriceFrom);

                    if (model.PriceTo.HasValue && model.PriceTo > 0)
                        query = query.Where(a => a.OwnerPrice <= model.PriceTo);

                    if (model.Size != null && model.Size.SizeNameId > 0)
                    {
                        query = query.Where(a => a.SizeNameId == model.Size.SizeNameId);

                        if (model.Size.SizeFrom.HasValue)
                            query = query.Where(a => a.SizeNameId == model.Size.SizeNameId && a.Size >= model.Size.SizeFrom && a.Size <= model.Size.SizeTo);
                    }

                    if (model.BuildActionTypes?.Length > 0)
                        query = query.Where(a => a.BuildAction != null && model.BuildActionTypes.Contains(a.BuildAction.Id));

                    if (model.BuildTypes?.Length > 0)
                        query = query.Where(a => a.BuildType != null && model.BuildTypes.Contains(a.BuildType.Id));

                    if (model.Rooms?.Length > 0)
                    {
                        foreach (var room in model.Rooms)
                        {
                            query = query.Where(a => a.BuildingRooms.Any(b => b.RoomType == room.Type && room.Count.Contains(b.RoomCount)));
                        }
                    }

                    switch (model.SortType)
                    {
                        case SortType.Asc:
                            query = query.OrderBy(a => a.OwnerPrice);
                            break;
                        case SortType.Desc:
                            query = query.OrderByDescending(a => a.OwnerPrice);
                            break;
                        case SortType.Newest:
                            query = query.OrderByDescending(a => a.CreatedDate);
                            break;
                    }

                    if (model.Points != null)
                    {
                        query = query.Where(a => a.Latitude.HasValue && a.Latitude >= model.Points.X1 && a.Latitude <= model.Points.X2 &&
                                                 a.Longitude.HasValue && a.Longitude >= model.Points.Y1 && a.Longitude <= model.Points.Y2);
                    }
                }
                var totalCount = query.Count();
                var result = query.Skip(model.PageSize * (model.CurrentPage - 1))
                                  .Take(model.PageSize)
                                  .AsEnumerable()
                                  .Select(a =>
                                  {
                                      var building = a.MapTo<BuildingShortDetailsViewModel>();
                                      building.LoadEntity(a);
                                      return building;
                                  });
                var searchResult = new SearchResult
                {
                    Filter = model,
                    Locations = query.Select(a => new LocationModel
                    {
                        BuildingId = a.Id,
                        Latitude = a.Latitude.ToString(),
                        Longitude = a.Longitude.ToString(),
                        OwnerPrice= a.OwnerPrice,
                        Size= a.Size,
                        SizeName= a.SizeName.Id,
                        BuildingPhotos= a.BuildingPhotos,
                        BuildAction=a.BuildAction.Id,
                    }),
                    Buildings = result,
                    TotalCount = totalCount
                };

                return Ok(searchResult);
            }
            catch (Exception ex)
            {
                return BadRequest($"Error occured while getting search result. Error: {ex.Message}. StackTrace: {ex.StackTrace}");
            }
        }

任何帮助表示赞赏

【问题讨论】:

    标签: sql-server performance indexing angular7 asp.net-core-2.1


    【解决方案1】:

    首先,避免

    var totalCount = query.Count();
    

    运行查询只是为了计算行数。只需告诉您的 UI 是否还有更多行,或者您是否在最后一页。

    我的数据库中有 1568 个数据(建筑物信息)

    如果数量很少,请考虑将它们全部缓存在您的 API 中,并在内存中的数据上运行该查询,而不是每次都查询数据库。

    您也可以在每个查询中都加载它们,并在内存中处理您的搜索逻辑。例如

    替换

    var query = _service.AllAsQueryable;
    

    与

    var query = _service.AllAsQueryable.ToList();
    

    【讨论】:

    • 感谢您的回答。我的数据每天都在增加,那么使用elasticsearch或sql server索引哪种方式更好,sql server中数据行的限制对性能有什么影响?
    • 有一种简单的方法可以为该进程查询使用索引。每个组合搜索选项都是一个不同的查询,会响应不同的索引。因此,您可能必须为每个查询扫描表。但是扫描这样的小桌子应该很快。
    猜你喜欢
    • 1970-01-01
    • 2019-05-23
    • 2019-01-24
    • 2019-03-24
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    相关资源
    最近更新 更多