Быстро прикрутить Paging к SQL запросу
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Быстро прикрутить Paging к SQL запросу
Глубоко в коде программы обнаружил проблему. На стороне UI есть grid, который отображает данные из таблицы по страницам. По 10 штук на страницу. Но логика выборки данных из базы сделана неправильно:
На каждый запрос от UI сначала достаются ВСЕ записи из таблицы в память и потом уже в памяти выбираются нужные страницы. Грубо говоря
var data = SELECT Column FROM Table
var result = data.Skip(...).Take(...);
База - SQL SERVER.
Нужно Paging делать внутри SQL запроса к базе, а не потом в памяти. Записей до хрена в таблице (больше миллиона).. запрос выполняется долго. Как быстро прикрутить paging к SQL запросу? какие операторы добавить в каком месте?
Основательно переделывать все времени нет. Код достался от прежнего девелопера, клиент орет что надо починить прямо щас...
На каждый запрос от UI сначала достаются ВСЕ записи из таблицы в память и потом уже в памяти выбираются нужные страницы. Грубо говоря
var data = SELECT Column FROM Table
var result = data.Skip(...).Take(...);
База - SQL SERVER.
Нужно Paging делать внутри SQL запроса к базе, а не потом в памяти. Записей до хрена в таблице (больше миллиона).. запрос выполняется долго. Как быстро прикрутить paging к SQL запросу? какие операторы добавить в каком месте?
Основательно переделывать все времени нет. Код достался от прежнего девелопера, клиент орет что надо починить прямо щас...
-
- Уже с Приветом
- Posts: 1494
- Joined: 08 Mar 2002 10:01
- Location: NJ
-
- Новичок
- Posts: 73
- Joined: 23 Dec 2012 03:53
- Location: KGF>SVO>ORD>DFW
Re: Быстро прикрутить Paging к SQL запросу
OFFSET/FETCH
OFFSET/LIMIT
если вы планируете использовать paging с ORDER BY по не уникальному полю
результат может быть не предсказуемым
OFFSET/LIMIT
если вы планируете использовать paging с ORDER BY по не уникальному полю
результат может быть не предсказуемым
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
-
- Уже с Приветом
- Posts: 1494
- Joined: 08 Mar 2002 10:01
- Location: NJ
Re: Быстро прикрутить Paging к SQL запросу
OLAP функции там должны быть. Можно сделать так, хотя это м.б. неоптимально
select * from (
select c1, c2, c3, row_number() over (order by c1) as rn
from test12
)
where rn between 10 and 20
select * from (
select c1, c2, c3, row_number() over (order by c1) as rn
from test12
)
where rn between 10 and 20
-
- Уже с Приветом
- Posts: 5777
- Joined: 13 Feb 2016 18:50
- Location: Кемерово
Re: Быстро прикрутить Paging к SQL запросу
https://www.google.de/search?q=sql+paging
я помню такой вопрос задавали Тому Кайту, когда ещё не было гугля.
открыл аскТом набрал paging в строке поиска: впервые такое спрашивали 17.6 лет назад!
https://asktom.oracle.com/pls/apex/f?p=100:1:::NO:::
Ёкарный бабай, как летит время! Я ведь тогда уже был отнюдь не юношей!
я помню такой вопрос задавали Тому Кайту, когда ещё не было гугля.
открыл аскТом набрал paging в строке поиска: впервые такое спрашивали 17.6 лет назад!
https://asktom.oracle.com/pls/apex/f?p=100:1:::NO:::
Ёкарный бабай, как летит время! Я ведь тогда уже был отнюдь не юношей!
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Re: Быстро прикрутить Paging к SQL запросу
Сделал это все через NHibernate. Вижу, что в итоговом SQL запросе используются TOP (...), ROW_NUMBER (). Все работает..
НО вот какая беда..
В запросе участвует View, которая собирает информацию для грида из 6ти разных таблиц. Количество записей в этом View много (примерно миллион). При каждом запросе к View создаются два запроса:
1. Первый что то типа SELECT COUNT (*) FROM View WHERE ... который возращает общее количество записей для моего запроса (нужно это число показать в Гриде).
2. Соответственно сам запрос, который возвращает нужную порцию данных (первые десять.. вторые десять.. и так далее).
Каким образом можно ускорить выполение данных запросов? Поможет ли в этом случае сделать мою View как indexed? в Indexed views довольно много ограничений, нельзя использовать LEFT, RIGHT joins и еще куча других. У меня во View есть LEFT joins, поэтому кластерный индекс создать не получится.
НО вот какая беда..
В запросе участвует View, которая собирает информацию для грида из 6ти разных таблиц. Количество записей в этом View много (примерно миллион). При каждом запросе к View создаются два запроса:
1. Первый что то типа SELECT COUNT (*) FROM View WHERE ... который возращает общее количество записей для моего запроса (нужно это число показать в Гриде).
2. Соответственно сам запрос, который возвращает нужную порцию данных (первые десять.. вторые десять.. и так далее).
Каким образом можно ускорить выполение данных запросов? Поможет ли в этом случае сделать мою View как indexed? в Indexed views довольно много ограничений, нельзя использовать LEFT, RIGHT joins и еще куча других. У меня во View есть LEFT joins, поэтому кластерный индекс создать не получится.
-
- Уже с Приветом
- Posts: 8239
- Joined: 06 Feb 2002 10:01
- Location: NJ, USA
Re: Быстро прикрутить Paging к SQL запросу
A чо, просто добавить счётчик в запрос ломает? Потом показывать значение из любой возващенной записи.
Code: Select all
select * from (
select v.*, row_number() over (order by 1, 2, 3) rn, count(1) over () total_records
from t_view v
where 1=1
) where rn between 20 and 30
order by rn
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Re: Быстро прикрутить Paging к SQL запросу
О спасибо. Интересный подход. Но не получится. Этот счетчик покажет общее количество записей во View. А если у меня есть критерии поиска какие то, то мне надо вернуть общее количество записей которые соответствуют этому критерию, а не ВСЕ записи из ViewUzito wrote: ↑12 Dec 2017 18:03 A чо, просто добавить счётчик в запрос ломает? Потом показывать значение из любой возващенной записи.
Code: Select all
select * from ( select v.*, row_number() over (order by 1, 2, 3) rn, count(1) over () total_records from t_view v where 1=1 ) where rn between 20 and 30 order by rn
-
- Уже с Приветом
- Posts: 8239
- Joined: 06 Feb 2002 10:01
- Location: NJ, USA
Re: Быстро прикрутить Paging к SQL запросу
Что значит не получится? Count(1) over () вернет количество отфильтрованых записей.shadow7256 wrote: ↑13 Dec 2017 00:47 О спасибо. Интересный подход. Но не получится. Этот счетчик покажет общее количество записей во View. А если у меня есть критерии поиска какие то, то мне надо вернуть общее количество записей которые соответствуют этому критерию, а не ВСЕ записи из View
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Re: Быстро прикрутить Paging к SQL запросу
Да, но только если условие выборки каким то образом добавляется в текст самого View. А у меня текст статический:Uzito wrote: ↑13 Dec 2017 03:54Что значит не получится? Count(1) over () вернет количество отфильтрованых записей.shadow7256 wrote: ↑13 Dec 2017 00:47 О спасибо. Интересный подход. Но не получится. Этот счетчик покажет общее количество записей во View. А если у меня есть критерии поиска какие то, то мне надо вернуть общее количество записей которые соответствуют этому критерию, а не ВСЕ записи из View
Code: Select all
CREATE VIEW [dbo].[TransactionsView]
AS
SELECT t.TransactionId, t.ClientId, t.TCN, t.Name, COUNT(1) over () TotalRecords
FROM dbo.Transactions as t
Code: Select all
SELECT TOP (10) this_.TransactionId, this_.ClientId, this_.TCN , this_.Name, this_.TotalRecords
FROM TransactionsView as this_
WHERE (this_.TCN like '%4401329997712%')
-
- Уже с Приветом
- Posts: 8239
- Joined: 06 Feb 2002 10:01
- Location: NJ, USA
Re: Быстро прикрутить Paging к SQL запросу
В моем примереshadow7256 wrote: ↑13 Dec 2017 15:07 Да, но только если условие выборки каким то образом добавляется в текст самого View. А у меня текст статический:
Code: Select all
where 1=1
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Re: Быстро прикрутить Paging к SQL запросу
Ага, это я понял, но к сожалению не получится вставитьUzito wrote: ↑13 Dec 2017 19:58В моем примереshadow7256 wrote: ↑13 Dec 2017 15:07 Да, но только если условие выборки каким то образом добавляется в текст самого View. А у меня текст статический:Это место, куда ваш фильтр вставлять.Code: Select all
where 1=1
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
Re: Быстро прикрутить Paging к SQL запросу
Hibernate зло
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
-
- Уже с Приветом
- Posts: 1494
- Joined: 08 Mar 2002 10:01
- Location: NJ
Re: Быстро прикрутить Paging к SQL запросу
Hibernate умеет вызывать процедуры?