MySQL Data - лучший способ реализовать пейджинг? - PullRequest
177 голосов
/ 26 сентября 2010

Приложение для iPhone подключается к моему веб-сервису PHP для извлечения данных из базы данных MySQL. Запрос может вернуть 500 результатов.

Каков наилучший способ реализовать подкачку и извлекать 20 элементов одновременно?

Допустим, я получил первые 20 объявлений из моей базы данных. Теперь, как я могу запросить следующие 20 объявлений?

Ответы [ 7 ]

268 голосов
/ 26 сентября 2010

Из документации MySQL :

Предложение LIMIT может использоваться для ограничения количества строк, возвращаемых оператором SELECT. LIMIT принимает один или два числовых аргумента, которые оба должны быть неотрицательными целочисленными константами (кроме случаев использования подготовленных операторов).

С двумя аргументами первый аргумент задает смещение первой строки, которую нужно вернуть, а второй - максимальное количество строк, которые нужно вернуть. Смещение начальной строки 0 (не 1):

SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

Чтобы извлечь все строки от определенного смещения до конца набора результатов, вы можете использовать некоторое большое число для второго параметра. Этот оператор извлекает все строки от 96-й строки до последней:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

С одним аргументом значение указывает количество строк, возвращаемых с начала набора результатов:

SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

Другими словами, LIMIT row_count эквивалентно LIMIT 0, row_count.

105 голосов
/ 26 сентября 2010

Для 500 записей эффективность, вероятно, не проблема, но если у вас есть миллионы записей, то может быть полезно использовать предложение WHERE для выбора следующей страницы:

SELECT *
FROM yourtable
WHERE id > 234374
ORDER BY id
LIMIT 20

Здесь "234374" - это идентификатор последней записи с предыдущей просмотренной вами страницы.

Это позволит использовать индекс по идентификатору для поиска первой записи. Если вы используете LIMIT offset, 20, вы можете обнаружить, что он становится все медленнее и медленнее по мере продвижения к концу. Как я уже сказал, это, вероятно, не имеет значения, если у вас есть только 200 записей, но это может иметь значение для больших наборов результатов.

Еще одним преимуществом этого подхода является то, что если данные меняются между вызовами, вы не пропустите записи или получите повторную запись. Это связано с тем, что добавление или удаление строки означает, что смещение всех строк после нее изменяется. В вашем случае это, вероятно, не важно - я думаю, что ваш пул рекламы не меняется слишком часто, и в любом случае никто не заметит, получат ли они одно и то же объявление дважды подряд - но если вы ищете «лучший способ» тогда это еще одна вещь, которую нужно иметь в виду при выборе того, какой подход использовать.

Если вы хотите использовать LIMIT со смещением (и это необходимо, если пользователь переходит непосредственно к странице 10000 вместо того, чтобы перелистывать страницы по одной), тогда вы можете прочитать эту статью о поздних поисках строк для улучшения производительности LIMIT с большим смещением.

21 голосов
/ 20 октября 2016

Определить OFFSET для запроса. Например

стр. 1 - (записи 01-10): смещение = 0, предел = 10;

стр. 2 - (записи 11-20) смещение = 10, предел = 10;

и используйте следующий запрос:

SELECT column FROM table LIMIT {someLimit} OFFSET {someOffset};

пример для страницы 2:

SELECT column FROM table
LIMIT 10 OFFSET 10;
20 голосов
/ 02 сентября 2015

Есть литература об этом:

Основная проблема возникает при использовании больших OFFSET с.Они избегают использования OFFSET с различными приемами, начиная от выбора диапазона id в предложении WHERE и заканчивая какими-то страницами кэширования или предварительного вычисления.

Предлагаются решения на Используйте ИНДЕКС, Люк :

11 голосов
/ 11 декабря 2013

Этот урок показывает отличный способ сделать нумерацию страниц. Эффективное разбиение на страницы с использованием MySQL

Короче, избегайте использования OFFSET или большого LIMIT

5 голосов
/ 23 апреля 2015

Запрос 1: SELECT * FROM yourtable WHERE id > 0 ORDER BY id LIMIT 500

Запрос 2: SELECT * FROM tbl LIMIT 0,500;

Запрос 1 выполняется быстрее с небольшими или средними записями, если число записей равно 5000 или выше, результат аналогичен.

Результат для 500 записей:

Запрос1 занимает 9.9999904632568 миллисекунд

Запрос2 занимает 19,9999980926514 миллисекунд

Результат для 8000 записей:

Запрос1 занимает 129,99987602234 миллисекунд

Запрос2 занимает 160,00008583069 миллисекунд

5 голосов
/ 26 сентября 2010

вы также можете сделать

SELECT SQL_CALC_FOUND_ROWS * FROM tbl limit 0, 20

Количество строк в операторе выбора (без ограничения) фиксируется в том же операторе выбора, поэтому вам не нужно снова запрашивать размер таблицы.Вы получаете количество строк, используя SELECT FOUND_ROWS ();

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