Постраничная разметка PostgreSQL вместе с индексацией номеров строк - PullRequest
0 голосов
/ 24 мая 2018

Хорошо, я работаю над переносом запроса базы данных oracle DB на postgres.Мой запрос должен дать мне пронумерованные записи и нумерацию страниц.

Рассмотрим следующий код оракула:

select * from (
    select RS.*, ROWNUM as RN from ( 
        select * from STUDENTS order by GRADES
    ) RS where ROWNUM <= (#{startIndex} + #{pageSize}) 
) where RN > #{startIndex}

Обратите внимание, что здесь есть 2 варианта использования ROWNUM:

  1. Чтобы указать номер строки для каждой строки в результате запроса.
  2. Для разбивки на страницы.

Мне нужно перенести такой запрос на postgres .

Я знаю, как разбивать на страницы, используя команды LIMIT и OFFSET для разбивки на страницы, но я не могу предоставить глобальный номер строки (каждая строка в результате запроса получает уникальный номер строки).

С другой стороны, мне удалось найти команду ROW_NUMBER(), которая может предоставить мне глобальные номера строк, но она не рекомендуется для целей нумерации страниц, поскольку число кортежей в моей БД очень большое.

Как написать аналогичный код в postgres?

1 Ответ

0 голосов
/ 24 мая 2018

Решение выглядит намного проще в PostgreSQL:

SELECT *,
       row_number() OVER (ORDER BY grades) AS rn
FROM students
ORDER BY grades
OFFSET $1 LIMIT $2;

Этот запрос эффективен, если существует индекс на grades и смещение не слишком велико:

EXPLAIN (ANALYZE)
SELECT *,
       row_number() OVER (ORDER BY grades) AS rn
FROM students
ORDER BY grades
OFFSET 10 LIMIT 20;

                             QUERY PLAN                                                                   
-------------------------------------------------------------------
 Limit  (cost=1.01..2.49 rows=20 width=20)
        (actual time=0.204..0.365 rows=20 loops=1)
   ->  WindowAgg  (cost=0.28..74.25 rows=1000 width=20)
                  (actual time=0.109..0.334 rows=30 loops=1)
         ->  Index Scan using students_grades_idx on students
                        (cost=0.28..59.25 rows=1000 width=12)
                        (actual time=0.085..0.204 rows=30 loops=1)
 Planning time: 0.515 ms
 Execution time: 0.627 ms
(5 rows)

Соблюдайте actual значения в плане.

Разбивка на страницы с OFFSET означает всегда неэффективно с большими смещениями;рассмотрим нумерацию клавиш .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...