2013-09-21 1 views
0

Есть ли лучший способ сделать подкачку на SQL-сервере?Лучшая техника разбивки на страницы в формате HTML

Например, я должен добавить @skip к @take, используя следующую методику:

;WITH tmp_cte AS (
SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, 
     LastName, 
     FirstName 
    FROM person.Person 
    WHERE FirstName like '%ad%' 
) 
SELECT * 
FROM tmp_cte 
WHERE RowNumber > @skip --10 
AND RowNumber <= @Take--20 

есть лучший способ, так что я не должен добавить пропуск взять?

+1

Основная проблема с производительностью будет состоять в следующем: 'FirstName like '% ad%'' и, во-вторых, разбиение на страницы (что будет проблемой с большими смещениями и если в общем случае будет много строк, соответствующих указанному выше первому условию.) –

+0

@ypercube: Не согласен. Основная проблема заключается в том, что это решение и решение с наибольшим числом. голосов недостаточно. Эти решения требуют больших индексов, а при большом числе страниц (в конце «ORDER BY LastName») производительность ухудшается. –

ответ

6

В SQL 2012 это очень просто:

SELECT LastName, FirstName 
    FROM person.Person 
WHERE FirstName like '%ad%' 
ORDER BY LastName 
OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY; 

Заканчивать this link для других версий серверов SQL + сравнения производительности.

0

Лучшее решение возможно, если есть уникальный индекс в таблице Person.Person (например, есть уникальный индекс в столбце PersonID, и этот индекс кластеризуется - например, если у вас есть кластерный ПК). В таких случаях выше запроса можно переписать следующим образом:

;WITH tmp_cte AS (
    SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, PersonID 
    FROM person.Person 
    WHERE FirstName like '%ad%' 
) 
SELECT ... 
FROM Person.Person p 
WHERE p.PersonID IN -- PersonID is the key of this UNIQUE INDEX 
(
SELECT PersonID FROM tmp_cte 
WHERE RowNumber > @skip 10 AND RowNumber <= @Take--20 
) 

или

DECLARE @Rows TABLE (ID INT PRIMARY KEY); 
;WITH tmp_cte AS (
    SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, PersonID 
    FROM person.Person 
    WHERE FirstName like '%ad%' 
) 
INSERT @Rows (ID) 
SELECT PersonID FROM tmp_cte 
WHERE RowNumber > @skip 10 AND RowNumber <= @Take--20 

SELECT ... 
FROM Person.Person p 
WHERE p.PersonID IN (SELECT ID FROM @Rows); -- PersonID is the key of this UNIQUE INDEX 

Примечание # 1: В данном конкретном случае, индекс по (FirstName, LastName) или (LastName, FirstName) может быть также полезно.

Примечание № 2: Это решение должно работать лучше, если в окончательном SELECT должно быть больше столбцов.

Смежные вопросы