Получение подмножества записей наряду с общим количеством записей

Я работаю над возвратом recordset от SQL Server 2008, чтобы сделать некоторое разбиение на страницы. Я только возвращаю 15 записей за один раз, но у меня должно быть общее количество соответствий наряду с подмножеством записей. Я использовал два различных запроса со смешанными результатами в зависимости от того, где в более многочисленной группе я должен вытянуть подмножество. Вот образец:

SET NOCOUNT ON;
WITH tempTable AS (
  SELECT
     FirstName
     , LastName
     , ROW_NUMBER() OVER(ORDER BY FirstName ASC) AS RowNumber 
   FROM People
   WHERE 
      Active = 1
)

SELECT 
   tempTable.*     
   , (SELECT Max(RowNumber) FROM tempTable) AS Records    
FROM tempTable     
WHERE
   RowNumber >= 1
   AND RowNumber <= 15
ORDER BY
   FirstName

Этот запрос работает действительно быстро, когда я возвращаю объекты на нижнем уровне соответствий, как записи 1 - 15. Однако, когда я начинаю возвращать записи 1000 - 1015, обработка перейдет из-под секунды больше чем к 15 секундам.

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

SET NOCOUNT ON;
WITH tempTable AS (
  SELECT * FROM (
     SELECT
        FirstName
        , LastName
        , ROW_NUMBER() OVER(ORDER BY FirstName ASC) AS RowNumber 
        , COUNT(*) OVER(PARTITION BY NULL) AS Records
      FROM People
      WHERE 
         Active = 1
   ) derived
   WHERE RowNumber >= 1 AND RowNumber <= 15
)

SELECT 
   tempTable.*     
FROM tempTable     
ORDER BY
   FirstName

Тот запрос выполняет высокие возвраты числа через 2-3 секунды, но также и выполняет запросы небольшого числа через 2-3 секунды также. Поскольку это делает счет для каждого из 70 000 + строки, это выполняет каждый запрос, занимают больше времени вместо просто больших номеров строк.

Таким образом, я должен выяснить, как получить хорошее количество строки, а также только возвратить подмножество объектов в любой точке в наборе результатов, не получая такой огромный штраф. Я мог обработать 2-3 вторых штрафа за высокие номера строк, но 15 слишком много, и я не готов перенести медленные загрузки на первых нескольких страницах, которые просматривает человек.

Примечание: Я знаю, что мне не нужен CTE во втором примере, но это - просто простой пример. В производстве я делаю дальнейшие соединения на поддающемся соблазну после того, как я отфильтровал его к этим 15 строкам, в которых я нуждаюсь.

6
задан Dan Short 6 January 2010 в 20:08
поделиться

2 ответа

Вот что я сделал (и это так же быстро, независимо от того, какие записи я вернул):

--Parameters include:
@pageNum int = 1,
@pageSize int = 0,



DECLARE 
    @pageStart int,
    @pageEnd int

SELECT
    @pageStart = @pageSize * @pageNum - (@pageSize - 1),
    @pageEnd = @pageSize * @pageNum;


SET NOCOUNT ON;
WITH tempTable AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY FirstName ASC) AS RowNumber,
        FirstName
        , LastName
    FROM People
    WHERE Active = 1
)

SELECT
    (SELECT COUNT(*) FROM tempTable) AS TotalRows,
    *
FROM tempTable
WHERE @pageEnd = 0
OR RowNumber BETWEEN @pageStart AND @pageEnd
ORDER BY RowNumber
8
ответ дан 16 December 2019 в 21:40
поделиться

В прошлом я справлялся с ситуацией, немного похожей на эту, не утруждая себя определённым количеством строк, а используя план запроса, чтобы дать мне примерное количество строк, немного похожее на то, что описывает первый элемент в этой ссылке:

http://www. sqlteam.com/forums/topic.asp?TOPIC_ID=108658

Затем было намерение доставить все строки, которые были запрошены в пределах диапазона (от, скажем, 900 до 915), а затем вернуть оценочное количество строк, например,

rows 900-915 of approx. 990

, что позволило избежать необходимости считать все строки. Как только пользователь выходит за пределы этой точки, я просто показываю

rows 1000-1015 of approx. 1015

, т.е. просто принимаю последний запрошенный ряд как мою новую оценку.

0
ответ дан 16 December 2019 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: