Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Paging. Как избавится от copy-paste кода  [new]
Abuserrr
Member

Откуда:
Сообщений: 268
Собственно нужно выбрать какую-то определенную страницу данных по некоторому критерию. А так же вернуть, сколько всего записей попадают под этот критерий. Ищу способ, как избавится от того, чтобы не copy-pastить критерий.

Вариант с copy-paste:
DECLARE @OwnerID INT, @PageNum INT, @PageSize INT
SET @OwnerID = 25
SET @PageNum = 1
SET @PageSize = 10;

SELECT COUNT(*) FROM dbo.Contact /*узнаем к-тво записей попадающие под критерий*/
WHERE OwnerID = @OwnerID /*для простоты оставил только одно условие*/;

WITH tt AS (
SELECT *, ROW_NUMBER() OVER(ORDER BY LastName) AS RowNum FROM dbo.Contact
WHERE OwnerID = @OwnerID  /*для простоты оставил только одно условие*/
)

SELECT tt.*
FROM tt	
WHERE tt.RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize

И вариант без copy-paste:
DECLARE @OwnerID INT, @PageNum INT, @PageSize INT
SET @OwnerID = 25
SET @PageNum = 1
SET @PageSize = 10;

WITH tt AS (
SELECT *, ROW_NUMBER() OVER(ORDER BY LastName) AS RowNum FROM dbo.Contact
WHERE OwnerID = @OwnerID /*нету copy-paste, все в одном месте*/
)

SELECT tt.*, T.TotalCount
FROM tt
	cross apply (SELECT MAX(RowNum) AS TotalCount FROM tt) T /*узнаем к-тво записей попадающие под критерий*/
WHERE tt.RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize

Собственно говоря помимо того, что есть не одно условие в WHERE, но и еще приходится джойнить другие таблицы и проверять на те или иные критерии, то copy-paste будет порядочно.

Из этого вопрос, насколько второй вариант будет медленнее?
з.ы. Можно правда еще лепить все в строчку и использовать что-то типа exec(@myConcatenateQuery), но не очень хочется.
3 авг 11, 18:51    [11067193]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
aleks2
Guest
Нихера не понятно, зачем там первый запрос

SELECT COUNT(*) FROM dbo.Contact /*узнаем к-тво записей попадающие под критерий*/
WHERE OwnerID = @OwnerID /*для простоты оставил только одно условие*/;

но ежели "шоб было", то рассмотрите вариант

WITH tt AS (
SELECT *, ROW_NUMBER() OVER(ORDER BY LastName) AS RowNum FROM dbo.Contact
WHERE OwnerID = @OwnerID  /*для простоты оставил только одно условие*/
)
SELECT tt.*, (select COUNT(*) cnt FROM tt) as cnt
FROM tt	
WHERE tt.RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
3 авг 11, 19:21    [11067294]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
Abuserrr
Member

Откуда:
Сообщений: 268
2 aleks2

Чтобы узнать к-тво записей всего. Вы же по сути предложили то же самое, что и я в своем втором варианте без copy-paste. А вопрос сводится к тому, будет ли этот вариант тормозить больше?
3 авг 11, 19:28    [11067316]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
Fire83
Member

Откуда: Гомель-Минск
Сообщений: 474
Abuserrr
2 aleks2

Чтобы узнать к-тво записей всего. Вы же по сути предложили то же самое, что и я в своем втором варианте без copy-paste. А вопрос сводится к тому, будет ли этот вариант тормозить больше?

Подзапрос во стором варианте не корреливанный, он выполнится только один раз и в первом и во втором случае. вывод - не будет
3 авг 11, 19:30    [11067318]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
Abuserrr
Member

Откуда:
Сообщений: 268
Fire83
Abuserrr
2 aleks2

Чтобы узнать к-тво записей всего. Вы же по сути предложили то же самое, что и я в своем втором варианте без copy-paste. А вопрос сводится к тому, будет ли этот вариант тормозить больше?

Подзапрос во стором варианте не корреливанный, он выполнится только один раз и в первом и во втором случае. вывод - не будет


Я понимаю, что подзапрос выполниться лишь один раз. Но тут дело в том, что я проверил на довольно большой выборке. И второй вариант в среднем почему-то выполняется на 20% медленнее в сравнении с вариантом, где COUNT(*). Или я может где-то туплю и эти запросы работают одинаково, либо есть какое-то пояснение в падении производительности.
3 авг 11, 19:39    [11067336]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
Fire83
Member

Откуда: Гомель-Минск
Сообщений: 474
Abuserrr
Fire83
пропущено...

Подзапрос во стором варианте не корреливанный, он выполнится только один раз и в первом и во втором случае. вывод - не будет


Я понимаю, что подзапрос выполниться лишь один раз. Но тут дело в том, что я проверил на довольно большой выборке. И второй вариант в среднем почему-то выполняется на 20% медленнее в сравнении с вариантом, где COUNT(*). Или я может где-то туплю и эти запросы работают одинаково, либо есть какое-то пояснение в падении производительности.

Тут ответ только один - планы выполения смотрите
3 авг 11, 19:43    [11067342]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
WITH tt AS (
SELECT *, ROW_NUMBER() OVER(ORDER BY LastName) AS RowNum, COUNT(*) OVER (PARTITION BY 1) AS cnt FROM dbo.Contact
WHERE OwnerID = @OwnerID  /*для простоты оставил только одно условие*/
)
SELECT tt.*
FROM tt	
WHERE tt.RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
3 авг 11, 20:30    [11067463]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
Еще проще
WITH tt AS (
SELECT *, ROW_NUMBER() OVER(ORDER BY LastName) AS RowNum, COUNT(*) OVER () AS cnt FROM dbo.Contact
WHERE OwnerID = @OwnerID  /*для простоты оставил только одно условие*/
)
SELECT tt.*
FROM tt	
WHERE tt.RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
3 авг 11, 21:07    [11067601]     Ответить | Цитировать Сообщить модератору
 Re: Paging. Как избавится от copy-paste кода  [new]
Abuserrr
Member

Откуда:
Сообщений: 268
2 invm
Ваш вариант работает еще медленней. На досуге посмотрю в екзекушен планы, а так думал может это известная какая-то проблема, вот и спросил.
4 авг 11, 12:39    [11070050]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить