Какой наиболее эффективный способ разбиения моего сайта на страницы при выполнении запросов с помощью SQL?
Вопрос
Я пытаюсь разбить результаты SQL-запроса на страницы для использования на веб-странице.Языком и серверной частью базы данных являются PHP и SQLite.
Код, который я использую, работает примерно так (нумерация страниц начинается с 0).
http://example.com/table?page=0
page = request(page)
per = 10 // results per page
offset = page * per
// take one extra record so we know if a next link is needed
resultset = query(select columns from table where conditions limit offset, per + 1)
if(page > 0) show a previous link
if(count(resultset) > per) show a next link
unset(resultset[per])
display results
Есть ли более эффективные способы разбиения на страницы, чем этот?
Одна из проблем, которую я вижу с моим текущим методом, заключается в том, что я должен сохранить все 10 (или сколько угодно) результатов в памяти, прежде чем начать их отображать.Я делаю это потому, что PDO не гарантирует, что количество строк будет доступно.
Является ли более эффективным выдавать COUNT(*)
запрашивать, чтобы узнать, сколько существует строк, а затем передавать результаты в браузер?
Является ли это одним из тех, "это зависит от размера вашей таблицы и от того, является ли count(*)
запрос требует полного сканирования таблицы в серверной части базы данных", "выполните какое-нибудь профилирование самостоятельно" и тому подобные вопросы?
Решение
я бы предложил сначала просто произвести подсчет.счетчик (первичный ключ) - это очень эффективный запрос.
Другие советы
Я решил использовать метод запроса COUNT (*) two, потому что он позволяет мне создать ссылку непосредственно на последнюю страницу, чего не позволяет другой метод.Выполнение подсчета в первую очередь также позволяет мне передавать результаты в потоковом режиме, и поэтому они должны хорошо работать с большим количеством записей при меньшем объеме памяти.
Согласованность между страницами для меня не проблема.Спасибо вам за вашу помощь.
Есть несколько случаев, когда у меня есть довольно сложный запрос (объединение таблиц 9-12), возвращающий много тысяч строк, которые мне нужно разбить на страницы.Очевидно, что для правильной разбивки на страницы вам нужно знать общий размер результата.С базами данных MySQL использование директивы SQL_CALC_FOUND_ROWS в SELECT может помочь вам легко достичь этого, хотя вопрос о том, будет ли это более эффективным для вас, еще не решен.
Однако, поскольку вы используете SQLite, я рекомендую придерживаться подхода с двумя запросами. Здесь это очень краткая тема по этому вопросу.
Я сомневаюсь, что для ваших пользователей будет проблемой ждать, пока серверная часть вернет десять строк.(Вы можете компенсировать это, хорошо указав размеры изображения, заставив веб-сервер согласовывать передачу сжатых данных, когда это возможно, и т.д.)
Я не думаю, что вам будет очень полезно выполнить count(*) на начальном этапе.
Если вы занимаетесь каким-то сложным кодированием:Когда пользователь просматривает страницу x, используйте ajax-подобную магию для предварительной загрузки страницы x + 1 для улучшения работы пользователя.
Общее замечание о разбивке на страницы:Если данные изменяются во время просмотра пользователем ваших страниц, это мочь это может стать проблемой, если ваше решение требует очень высокого уровня согласованности.Я написал об этом заметку в другом месте.