[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Пагинация, елы палы
Эли4ка
Добрый день, дорогие участники форума. Возник вопрос, который никак не могу решить. Делаю пагинацию, и не знаю, как выбирать чем выбирать запросы
Либо
SQL_CALC_FOUND_ROWS и FOUND_ROWS()

Либо так
COUNT(*)

Чем плох первый случай. Если найдено будет 20 записей, на страничку выводится по 10, то всего должно быть 2 страницы, а если злоумышленник введет 40 страницу, то запрос все равно выполниться, то есть в первом запросе нужно тоже вставить
COUNT(id)
чтобы проверить на максимальное количество страниц.
Очень хотелось бы узнать, как это реализовано на этом форуме, так как тут и нагрузка большая и почти везде используется пагинация. И заметила, что если ввести страницу которая больше, чем максимальная, выбрасывает на последнюю.
Спасибо.
twin
Цитата (Эли4ка @ 30.03.2017 - 15:05)
а если злоумышленник введет 40 страницу, то запрос все равно выполниться

Ну и пусть. Тебе то что)) Последнюю страницу можно вычислить на стороне PHP, и дальше не пускать.

Первый случай плох вовсе не этим, а производительностью. Он хорош при сложных запросах, когда нельзя получить COUNT()

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Эли4ка
Поняла)
Но а как на этом форуме реализовано? можно узнать? или в личку, например. Ведь тут если ввести страницу заведомо не существующую, то перекинет на последнюю существующую.
T1grOK
Считаем отдельным запросом количество (и можем посчитать общее кол-во страниц), и отдельным тянем данные

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
Kusss
Цитата (twin @ 30.03.2017 - 19:37)
Первый случай плох вовсе не этим, а производительностью. Он хорош при сложных запросах, когда нельзя получить COUNT()

Ну я использую SQL_CALC_FOUND_ROWS
Вроде нормуль работает.
0.0668 - без
0.0676 - с

Запрос правда не простой, используется 8 таблиц.

Или это начинает сказывается когда записей становится очень много ? Тут то всего 13к записей в основной таблице.
AllesKlar
Цитата (T1grOK @ 30.03.2017 - 18:24)
Считаем отдельным запросом количество (и можем посчитать общее кол-во страниц), и отдельным тянем данные

Эдак можно дойти и до построчного чтения :)

Эли4ка
Если запрос простой, а-ля select * from thema t left join messages m (on m.thema_id = t.id) limit x ,y
то лучше с count(id) , т.к. обойдешься одним запросом.
На случай злоумышленника, который введет страницу 100500, отправишь еще один запрос, чтобы данные последней страницы получить. Таких "еще одних запросов" будет за всю историю три или пять.

Если же запрос сложный, то да, два запроса
select SQL_CALC_FOUND_ROWS * from table_name limit x, y;
SELECT FOUND_ROWS();



_____________
[продано копирайтерам]
Эли4ка
AllesKlar
Спасибо smile.gif
Эли4ка
Kusss
А можно пример вашего запроса?
Просто как бы я пробовала сама делать различные ситуации, но все-таки у меня это тесты, а хотелось бы реальные..
Kusss
SELECT 
SQL_CALC_FOUND_ROWS

p.id, p.price, p.price2, p.print_id, p.up_down, p.instagram, p.instagram_date,
(
SELECT img FROM `product_img` WHERE product_id = s.product_id AND sort IN (1) AND color NOT IN (156,157, 158,159, 160,161, 162,163) ORDER BY RAND() LIMIT 0,1) AS img2,
concat(YEAR(p.start), DATE_FORMAT(p.start, '%m')) AS Ym, /* Заменил на DATE_FORMAT(p.start, '%Y%m') */
TO_DAYS( '2017-03-31 00:00:00' ) - TO_DAYS(p.start) AS `day`,
(
SELECT SUM(sklad) FROM `product_sale` WHERE product_id = s.product_id GROUP BY product_id) AS sklad, /* Заменил на SUM(s.sklad) */
r2.tovar_prefix,
IF (print.name_ru IS NOT NULL, print.name_ru, p.name) AS name, /* Заменил на IFNULL(print.name_ru, p.name)*/
IF (print.name_eng IS NOT NULL, print.name_eng, p.name_eng) AS name_eng, /* Заменил на IFNULL(print.name_eng, p.name_eng) */
( SUM(s.sale_cof) + s.new + p.up_down) AS number,
SUM(s.sale) AS sale, s.new,
m.id AS main_id
FROM
`product_sale` AS s
LEFT JOIN
`product` AS p ON p.id = s.product_id
LEFT JOIN
`razdel` AS rr ON rr.id = p.razdel
LEFT JOIN
`print` AS print ON print.id = p.print_id
LEFT JOIN
`print_razdel` AS print_razdel ON print_razdel.print_id = p.print_id
LEFT JOIN
`razdel2` AS r2 ON r2.id = rr.razdel2_id
LEFT JOIN
`product_main` AS m ON m.print_id = p.print_id AND m.hide = 0
WHERE
rr.razdel2_id = 11 AND
print_razdel.print_razdel_id = 6 AND
p.print_id != 0 AND
p.live = 0 AND
p.sale = 0 AND
r2.hide = 0 AND
rr.hide = 0
GROUP BY
s.product_id
ORDER BY
number DESC,
p.id DESC
LIMIT

0,42

и общее количество строк
SELECT FOUND_ROWS( ) AS count


P.S. Как бывает полезно взглянуть на свой код через некоторое время.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.