Как ускорить денормализованную таблицу с индексами - PullRequest
0 голосов
/ 19 июня 2019

Я создал денормализованную таблицу, которая имеет 35 столбцов и 360 тыс. Записей. таблица состоит из 8 других таблиц. Таблица имеет только одно внутреннее соединение с другой таблицей.

Моя главная проблема - производительность, запросы к этой таблице работают очень медленно. У меня также есть полнотекстовый каталог, связанный с этой таблицей. Fts ищет также медленно. Также у меня есть тупики, в мониторе активности я вижу типы ожидания LCK_IM_X, LCK_IM_S.

Я помещал индексы как сумасшедшие и следовал планам выполнения запросов. Теперь я знаю, что сканирование таблицы плохо при слишком большом количестве записей. Я прошел это давным-давно, но сейчас сканирование индекса идет со стоимостью 80%.

Ниже, внутри select происходит из другой таблицы в виде строки, этот запрос работает очень быстро с максимальной скоростью. Кроме того, я динамически строю предложение where вместе с другими условиями. a busy cat https://imgur.com/a/ijOUYeY

SET @Sql=';WITH TempResult AS(Select '+(SELECT STUFF((SELECT ',' +DBFieldName FROM TableFields where TableFields.TableID=3 FOR XML PATH('')), 1, 1, ''))+',
0 as [DeviceChange],
0 as [DeviceReturn],
0 as [SNORepeat]
 from DenormalizedTable
inner join Companies On Companies.CompanyID=DenormalizedTable.CompanyID
WHERE  (@state is null or DenormalizedTable.StateID=@state) 
            AND ((@status = -1 AND DenormalizedTable.Status IN(0,1,10,11,4)) OR (@status=1 AND DenormalizedTable.Status IN(1,4,10,11)) OR
             (@status=2 AND DenormalizedTable.Status IN (0))) AND (@CategoryID is null or DenormalizedTable.CategoryID=@CategoryID)
             AND (DenormalizedTable.CompanyID=@companyID OR Companies.SubCompanyOf=@companyID)
                 '+ ( CASE WHEN @CustomSearchParam='' THEN '' ELSE (Select dbo.[perf_whereBuilder](@CustomSearchParam)) END)+'
             AND (@technicianID is null or DenormalizedTable.JobOrderID IN (Select AttendedStaff.JobOrderID from AttendedStaff Where AttendedStaff.StaffID=@technicianID))
             AND (@FilterStartDate is null or convert(varchar, JobOrder_PerfTable.StartDate, 20) between @FilterStartDate and @FilterEndDate) 
), TotalCount AS (Select COUNT(*) as TotalCount from TempResult)

        Select * from TempResult, TotalCount 
          order by 1  desc 

            OFFSET     @skip ROWS      
FETCH NEXT @take ROWS ONLY;';

когда я запускаю sp, он загружается почти 5 секунд. если есть какой-либо параметр поиска, он идет еще больше.

Мне нужно знать, что мне нужно сделать, чтобы выполнить запрос быстрее, извините, если вопрос широкий.

...