SQL: выбор из View with OFFSET из двух баз данных работает бесконечно - PullRequest
0 голосов
/ 07 января 2020

Я работаю над проектом ASP. Net Core MVC, в котором мы используем сетку MVC6 (https://mvc6-grid.azurewebsites.net/), чтобы показать некоторые сетки. Чтобы наилучшим образом использовать сетку, мы используем SQL представлений и передаем их напрямую через Queryables в Entity Framework, поэтому мы можем позволить сетке фильтровать все на SQL напрямую.

Все работает хорошо, но для одного просмотра нам нужно объединить данные из другой базы данных. Из того, что я прочитал, лучший способ сделать это - через OpenQuery, так как я получаю только выбранные поля. Таким образом, объединение в представлении выглядит следующим образом:

                SELECT  Stuff
                FROM    dbo.Licenses lic
                LEFT OUTER JOIN 
                (
                    SELECT * FROM OPENQUERY([Server],'SELECT identUser.UserName, identUser.id FROM [Database].dbo.IdentityUsers identUser')
                ) AS identUser on identUser.id = lic.OwnerId

Выбор данных в представлении выполняется не слишком быстро, но он работает. К сожалению, у нас также есть глобальный поиск в сетке, который ищет все доступные поля в представлении. Эта функция напрямую не поддерживается сеткой MVC6, поэтому я использую шаблон репозитория для подготовки Queryable. Код C# выглядит следующим образом

        public IQueryable<LicenseOverviewGridItem> QueryOverview(string searchTerm)
        {
            if (string.IsNullOrEmpty(searchTerm))
            {
                return _adminDbContext.LicenseOverviewGridItems;
            }

            return _adminDbContext.LicenseOverviewGridItems
                .Where(
                    f =>
                        f.ActivationDateDescription.Contains(searchTerm) ||
                        f.ExpiryDateDescription.Contains(searchTerm) ||
                        f.LicenseDurationInDaysDescription.Contains(searchTerm) ||
                        f.LicenseName.Contains(searchTerm) ||
                        f.OrganizationName.Contains(searchTerm) ||
                        f.ProductName.Contains(searchTerm) ||
                        f.StateDescription.Contains(searchTerm) ||
                        f.TypeDescription.Contains(searchTerm) ||
                        f.UserName.Contains(searchTerm) ||
                        f.RightsOfUseDescription.Contains(searchTerm)
                );
        }

Теперь эта комбинация становится проблемной c, поскольку сетка MVC6 создает следующий запрос:

exec sp_executesql N'SELECT [l].[ActivationDate], [l].[ActivationDateDescription], [l].[ExpiryDate], [l].[ExpiryDateDescription], [l].[LicenseDurationInDays], [l].[LicenseDurationInDaysDescription], [l].[LicenseId], [l].[LicenseName], [l].[OrganizationName], [l].[ProductName], [l].[RightsOfUse], [l].[RightsOfUseDescription], [l].[StateDescription], [l].[TypeDescription], [l].[UserName]
FROM [LicenseOverviewGridItems] AS [l]
WHERE (((((((((((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[ActivationDateDescription]) > 0)) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[ExpiryDateDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[LicenseDurationInDaysDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[LicenseName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[OrganizationName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[ProductName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[StateDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[TypeDescription]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[UserName]) > 0))) OR (((@__searchTerm_0 = N'''') AND @__searchTerm_0 IS NOT NULL) OR (CHARINDEX(@__searchTerm_0, [l].[RightsOfUseDescription]) > 0))
ORDER BY (SELECT 1)
OFFSET 0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__searchTerm_0 nvarchar(4000),@__p_1 int',@__searchTerm_0=N'delaquis',@__p_1=5

Проверка проблемы , комбинация

OFFSET 0 ROWS FETCH NEXT @__ p_1 ROWS ONLY

и

CHARINDEX (@__ searchTerm_0, [l]. [UserName])> 0

Причина и бесконечность l oop. Если я удаляю какую-либо часть, она работает нормально.

На целевом сервере я также создал индекс для identUser.UserName, identUser.id, но без помощи. Также я не смогу использовать индексированное представление. , поскольку SCHEMABINDING не поддерживается для выбора нескольких баз данных.

У меня заканчиваются варианты, что я могу сделать. Я мог бы переделать весь Queryying и обработать его вручную, но это, очевидно, довольно много изменений. Возможно ли при этом улучшение производительности?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...