Общее число строк смещения SQL медленно с предложением IN - PullRequest
5 голосов
/ 05 ноября 2019

Я использую этот sql на основе другого ответа, однако при включении массива в пунктах дела сводятся к получению общего количества. Если я удаляю общее количество, тогда запрос занимает менее 1 секунды. Есть ли лучший, более эффективный способ получить общее количество строк? Ответы, которые я видел, основаны на запросах sql 2013

DECLARE 
    @PageSize INT = 10, 
    @PageNum  INT = 1;

WITH TempResult AS(
    SELECT ID, Name
    FROM Table
     Where ID in ( 1 ,2 3, 4, 5, 6, 7, 8, 9 ,10)
), TempCount AS (
    SELECT COUNT(*) AS MaxRows FROM TempResult
)
SELECT *
FROM TempResult, 
 TempCount    <----- this is what is slow. Removing this and the query is super fast
ORDER BY TempResult.Name
    OFFSET (@PageNum-1)*@PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY

Ответы [ 11 ]

0 голосов
/ 11 ноября 2019

ИМХО, в таком вопросе всегда реальная просьба помочь в выявлении всех неэффективных факторов.

Нет сомнений Count(*) является одним из неэффективных факторов.

Другим важным неэффективным фактором являетсяOrder By Name

Order by varchar столбец, Order by Wide column, Order by Non Index столбец всегда медленный.

Если размер страницы увеличивается, это повлияет на производительность.

Итак, обратите внимание, что если ваше требование может быть изменено.

У меня есть индекс по 3 столбцам в этой таблице, и в запросе есть одно объединение. Эта объединенная таблица также имеет индекс для тех же соединяемых столбцов.

Не видя реального запроса и того, как выполняется соединение, ничего нельзя сказать.

Какая таблица имеет какСколько строк? И после присоединения Resultset есть сколько строк?

Вы можете однажды попробовать это,

DECLARE 
    @PageSize INT = 10, 
    @PageNum  INT = 1;

Declare @MaxRows int
create table #TempResult(tid int identity(1,1) primary key, id int,name varchar(50))
insert into #TempResult(id,name)
SELECT ID, Name
    FROM Table
     Where ID in ( 1 ,2 3, 4, 5, 6, 7, 8, 9 ,10)

select TOP @MaxRows=tid from #TempResult order by tid desc

--OR

--select  @MaxRows=max(tid) from #TempResult 

SELECT id,name
FROM #TempResult, 
 @MaxRows as TempCount    
ORDER BY TempResult.Name
    OFFSET (@PageNum-1)*@PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY

Вы можете поместить записи таблицы, в которой больше строк, в #TempResult.

Тогда при окончательном выборе вы можете join small table, если Total Rows in temp table - correct ответ.

Не зная реального сценария, не могу сказать Index сделать в #TempResult

Должен быть лучший способ получить счетчик в запросе смещения нумерации страниц

Если общее количество нужно взять изв таком случае,

SELECT SUM(s.row_count) FROM sys.dm_db_partition_stats s
WHERE s.[object_id] = OBJECT_ID('Table')
    AND s.index_id < 2

Использование Hint часто является опасной идеей. Если запрос не работает нормально, то причиной являются другие факторы, которые уже обсуждаются здесь (с любой имеющейся у нас информацией), часто.

Эксперт думает об использовании HINT в нескольких своих запросах. HINT это своего рода Hacк.

...