Вы не можете знать, что такое первый идентификатор на данной странице, потому что номера идентификаторов не обязательно являются последовательными. Другими словами, в последовательности могут быть пробелы, поэтому строки на пятой странице из 100 строк не обязательно начинаются с идентификатора 500. Например, он может начинаться с id 527. Это невозможно узнать.
Одно из возможных решений, если ваш клиент продвигается через страницу в порядке возрастания, что каждый запрос REST извлекают данные, отмечает наибольшее значения идентификатора на этой странице, а затем использует, что в следующем запросе покоятся поэтому запросы значения id больше.
SELECT ... FROM ... WHERE filterKey = filterValue
AND id > id_of_last_match_of_previous_page
Но если ваш запрос REST может получить любую случайную страницу, это решение не будет работать. Это зависит от того, что вы уже сделали предварительную страницу.
Другим решением является использование синтаксиса LIMIT <x> OFFSET <y>
. Это позволяет запросить любую произвольную страницу. LIMIT <y>, <x>
работает одинаково, но по какой-то причине x и y обращаются в двух разных синтаксических формах, поэтому имейте это в виду.
Использование LIMIT...OFFSET
не очень эффективно, когда вы запрашиваете страницу с большим количеством страниц в результате. Скажем, вы запрашиваете 5000-ю страницу. MySQL должен сгенерировать результат на стороне сервера из 5000 страниц, затем отбросить 4 999 из них и вернуть последнюю страницу в результате. Извините, но так оно и работает.
Re ваш комментарий:
Вы должны понимать, что WHERE
применяет условия на значений в строках, но страницы определяются позиции строк. Это два разных способа определения строк!
Если у вас есть столбец, который должен быть номер строки, то вы можете использовать это значение как позицию строки. Вы можете даже нанести на него индекс или использовать его в качестве первичного ключа.
Но значения первичного ключа могут меняться и не быть последовательными, например, если вы обновляете или удаляете строки или откатываете некоторые транзакции и т. Д. Перенумерация значений первичного ключа является плохой идеей, потому что другие таблицы или внешние данные могут ссылаться на значения первичного ключа.
Таким образом, вы можете добавить еще один столбец , а не первичный ключ, но только номер строки.
ALTER TABLE MyTable ADD COLUMN row_number BIGINT UNSIGNED, ADD KEY (row_number);
Затем заполните значения, когда вам нужно изменить нумерацию строк.
SET @row := 0;
UPDATE MyTable SET row_number = (@row := @row + 1) ORDER BY id;
Вам нужно будет повторно указать строки, если вы когда-нибудь удалите их, например. Это не эффективно делать это часто, в зависимости от размера таблицы.
Кроме того, новые вставки не могут создавать правильные значения числа строк без блокировки таблицы. Это необходимо для предотвращения условий гонки.
Если у вас есть гарантия, что row_number
представляет собой последовательность последовательных значений, то это как значение, так и позиция строки, поэтому вы можете использовать его для высокопроизводительных индексных поисков для любой произвольной страницы строк.
SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;
По крайней мере, до следующего раза последовательность номеров строк ставится под сомнение удалением или новыми вставками.
Это кажется странным способом сделать это. Стандартом для небольших/средних наборов данных в моей экспирации является ORDER BY по строкам, поэтому вы получаете согласованный набор данных (так что вы можете использовать все, что есть), затем используйте LIMIT и, как я подозреваю, вы, возможно, пропустили, предложение OFFSET для сообщите MySQL, чтобы они возвращали строки из позиции X. –
Насколько велик размер отфильтрованных данных? – Strawberry
Джон - Я понимаю, я не был знаком с СМЕЩЕНИЕМ, спасибо. Клубника - я хотел бы получить что-то вроде 200 строк за раз, от фильтрованных результатов, которые могут доходить до сотен тысяч. –