[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Пагинатор
Vladimir67
Всем доброй ночи.
Стал смотреть пагинатор от IRBIS.
Что-то не могу врубиться -
есть функция
public function countQuery($query) 
{

$query = str_replace("\n", " ", $query);
preg_match("#FROM(.+)#i", $query, $table);

$result = mysql_query("SELECT COUNT(*) AS `cnt` FROM ". $table[1]);

$this->TableCount = mysql_result($result, 0);

$res = mysql_query($query . $this->createLimit());

return $res;
}

Если я правильно понимаю, делаем 2 вещи.
1. Определяем, сколько всего записей в запросе,- COUNT....
2. Получаем результут самого запроса -
$res = mysql_query($query . $this->createLimit());

В запросе может быть куча условий WHERE (...путин > $prochorov AND.....)
Вопрос.
На черта тогда еще дополнительная функция (то бищь метод),
который идет ниже.
public function calcQuery($query)
    {
// Заменяем SELECT на SELECT SQL_CALC_FOUND_ROWS
$query = preg_replace('#SELECT#i', 'SELECT SQL_CALC_FOUND_ROWS ', $query);
// Выполняем основной запрос
$res = mysql_query($query . ' LIMIT '. $this->NumPage .', '. $this->NumRows * $this->NumColumns);
// Считаем к-во рядов
$this->TableCount = mysql_result(mysql_query('SELECT FOUND_ROWS()'), 0);
// Запускаем метод для менюшки
$this->createLimit();

return $res;
}

Спасибо.



Спустя 6 часов, 40 минут, 38 секунд (13.03.2012 - 06:15) twin написал(а):

Спустя 11 часов, 14 минут, 5 секунд (13.03.2012 - 17:29) glock18 написал(а):
Цитата (akuchkovsky @ 13.03.2012 - 03:33)
Vladimir67, twin - спасибо, я так бы и не узнал про существование такой возможности в этом классе, век живи век учись(!) laugh.gif

twin, ты на меня не злись только, но уж больно формулировка "Сложные запросы" непонятна. А еще для развития учеников полезно было бы написать, почему SQL_CALC_FOUND_ROWS медленнее бывает. Тогда формулировка "Сложные запросы" сама уйдет smile.gif

Спустя 2 часа, 57 минут, 48 секунд (13.03.2012 - 20:27) twin написал(а):
Цитата (glock18 @ 13.03.2012 - 14:29)
Цитата (akuchkovsky @ 13.03.2012 - 03:33)
Vladimir67, twin - спасибо, я так бы и не узнал про существование такой возможности в этом классе, век живи век учись(!)  laugh.gif

twin, ты на меня не злись только, но уж больно формулировка "Сложные запросы" непонятна. А еще для развития учеников полезно было бы написать, почему SQL_CALC_FOUND_ROWS медленнее бывает. Тогда формулировка "Сложные запросы" сама уйдет smile.gif

Вась, привет. Ты о чем, как можно злиться))) Если бы не твои советы и не наши споры, я бы наверно долго еще бы буксовал. А пагинатор у меня на старом сайте, я его почти не поддерживаю. Хотя нужно обновить, там куча ляпов. Время бы найти)))

Спустя 2 часа, 46 минут, 26 секунд (13.03.2012 - 23:14) glock18 написал(а):
Цитата (twin @ 13.03.2012 - 17:27)
Цитата (glock18 @ 13.03.2012 - 14:29)
Цитата (akuchkovsky @ 13.03.2012 - 03:33)
Vladimir67, twin - спасибо, я так бы и не узнал про существование такой возможности в этом классе, век живи век учись(!)  laugh.gif

twin, ты на меня не злись только, но уж больно формулировка "Сложные запросы" непонятна. А еще для развития учеников полезно было бы написать, почему SQL_CALC_FOUND_ROWS медленнее бывает. Тогда формулировка "Сложные запросы" сама уйдет smile.gif

Вась, привет. Ты о чем, как можно злиться))) Если бы не твои советы и не наши споры, я бы наверно долго еще бы буксовал. А пагинатор у меня на старом сайте, я его почти не поддерживаю. Хотя нужно обновить, там куча ляпов. Время бы найти)))

да, дискуссии пылкие были, что и говорить smile.gif

Понимаю, сам здесь что-то выкладывал - если бы задался целью пересмотреть это все на предмет ляпов, то едва ли даже нашел бы что-то laugh.gif Уже и не вспомню, что именно выкладывал smile.gif

Спустя 26 минут, 36 секунд (13.03.2012 - 23:40) Vladimir67 написал(а):
Да....
1. Спасибо.
2. Прочитал, но..., возможно мало виски выпил...
Во второй функции пример, надо полагать, сложного запроса.
И что такое не сложный запрос, где нет условий выборки?... (WHERE....)?
// Запрос 
$res = mysql_query("SELECT * FROM `table` WHERE `text` LIKE '%2%'");

Если я буду обрабатывать этот запрос первой функцией,
что не сработает?
Там стоит
 $result = mysql_query("SELECT COUNT(*) AS `cnt` FROM ". $table[1]);

Мне кажется, что в $table[1] будет стоять
`table` WHERE `text` LIKE '%2%.
И функцию SELECT SQL_CALC_FOUND_ROWS
с успехом выполнит обычный COUNT(*).
Где ошибка в моих рассуждениях?
То есть пока не понимаю - на черта эта вторая функция????

Спустя 1 час, 17 минут, 6 секунд (14.03.2012 - 00:57) Vladimir67 написал(а):
P.S.
Еще по ходу вопрос.
public function calcQuery($query) 
{
// Заменяем SELECT на SELECT SQL_CALC_FOUND_ROWS
$query = preg_replace('#SELECT#i', 'SELECT SQL_CALC_FOUND_ROWS ', $query);

Это во второй функции.
Почему preg_replace используется,
а не substr_replace(), то есть зачем из пушки по воробьям...?

Спустя 6 часов, 21 минута, 36 секунд (14.03.2012 - 07:19) twin написал(а):
Цитата (Vladimir67 @ 13.03.2012 - 20:40)
И что такое не сложный запрос, где нет условий выборки?... (WHERE....)?

Нет, сложный запрос, это допустим составной запрос. Из нескольких таблиц, с применением JOIN, UNION и так далее. В таком запросе невозможно подсчитать к-во строк в таблице. Таблиц то несколько и результат непредсказуем. Для этого и используется SQL_CALC_FOUND_ROWS
Подробности сам ищи))

Цитата
Почему preg_replace используется,
а не substr_replace(), то есть зачем из пушки по воробьям...?
Да, действительно. Только не substr_replace() наверное, а str_ireplace() лучше. А там стояла preg_replace() с модификатором i потому что запросы пишут кто как. кто в верхнем, кто в нижнем регистре... Бардак.

Спустя 49 минут, 3 секунды (14.03.2012 - 08:08) glock18 написал(а):
Цитата (twin @ 14.03.2012 - 04:19)
Нет, сложный запрос, это допустим составной запрос. Из нескольких таблиц, с применением JOIN, UNION и так далее. В таком запросе невозможно подсчитать к-во строк в таблице. Таблиц то несколько и результат непредсказуем. Для этого и используется SQL_CALC_FOUND_ROWS
Подробности сам ищи))


twin, ты серьезно что ли? ohmy.gif

Спустя 7 минут, 44 секунды (14.03.2012 - 08:16) twin написал(а):
А что не так?

Спустя 24 минуты, 32 секунды (14.03.2012 - 08:40) glock18 написал(а):
ну как, что... Возможно, тут ограничения пагинатора какие-то, но наличие одного-двух джойнов вовсе не значит, что нужно считать ряды SQL_CALC_FOUND_ROWS. SQL_CALC_FOUND_ROWS в сравнении с каунтом не использует индексы, а потому на больших выборках он все хуже и хуже становится. Используйте каунт, правильно стройте запрос и индексируйте таблицы rolleyes.gif

Вообще говоря единственное место, где я бы его мог посоветовать использовать - запросы на одну таблицу с условиями выборки, не покрытыми индексами. Хотя как по мне, то лучше покрыть их индексами и выбирать каунтом

Спустя 55 минут, 45 секунд (14.03.2012 - 09:36) twin написал(а):
Я это все прекрасно понимаю, я даже делал замеры и сюда выкладывал, лень искать.
Вот цитата из описания пагинатора:
Цитата
У Вас может возникнуть вопрос - а почему отдельным методом. Почему это не сделать сразу?
Ответ тревиален. Дело в том, что запрос с SQL_CALC_FOUND_ROWS работает гораздо медленнее, чем обычный. И использовать его нужно только там, где это действительно необходимо.

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

Спустя 27 минут, 7 секунд (14.03.2012 - 10:03) glock18 написал(а):
Цитата (twin @ 14.03.2012 - 06:36)
Я это все прекрасно понимаю, я даже делал замеры и сюда выкладывал, лень искать.
Вот цитата из описания пагинатора:
Цитата
У Вас может возникнуть вопрос - а почему отдельным методом. Почему это не сделать сразу?
Ответ тревиален. Дело в том, что запрос с SQL_CALC_FOUND_ROWS работает гораздо медленнее, чем обычный. И использовать его нужно только там, где это действительно необходимо.

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

да, глянул из любопытства пагинатор. Как раз по этому причине, и отметил, что не сказано о минусах SQL_CALC_FOUND_ROWS - только то, что они есть.

вот цитата по ссылке, которая в купе с твоим определением сложного запроса несколько не стыкуется
Цитата

Когда потребуется отлистать результаты сложного запроса, вместо метода countQuery() нужно вызвать метод calcQuery() и все будет чики-пики.


Вообще если позволишь, я заметил уже давно, что у тебя в курсах есть нераскрытые понятия, и вот конкретно в этом случае получается, что обычное значение понятия не стыкуется с реальностью в плане использования SQL_CALC_FOUND_ROWS.
Я бы посоветовал вам в будущем все же в уроках определения писать, или же ввести глоссарий. Поскольку, у вас, раньше по крайней мере, было много полных новичков, они все это на веру воспринимают, и может получиться немного поповский эффект, когда ввиду авторитета учителя, ученики его уверены в его словах больше, чем в себе самих sad.gif

PS: замеры кстати мы оба проводили, по-моему, я как раз тебя тогда убедить пробовал, что SQL_CALC_FOUND_ROWS плох почти всегда.

Об этой опции знать полезно, конечно, но важнее все таки знать, что она малополезна smile.gif Пардон, за тавтологию

Спустя 6 минут, 52 секунды (14.03.2012 - 10:10) glock18 написал(а):
Цитата (akuchkovsky @ 14.03.2012 - 06:52)
twin
Ничего... разберемся, а если что и свой пагинатор напишем smile.gif

Все вы так говорите wink.gif Потом писать начинаете, и оказывается половину не понимаете. Ну, я не о тебе конкретно, конечно, но подобных случаев было очень много. Я бы вам свою подпись на экран поклеил, и заставил вызубрить, прежде чем к коду подпускать biggrin.gif

Спустя 27 минут, 5 секунд (14.03.2012 - 10:37) twin написал(а):
glock18
Ну я помню нашу бталию на этот счет. Тут два момента. Я делал упор на простоту интеграции раз и касаемо сложных запросов и каунта ты меня тогд не убедил. Я потому и делал замеры. Я нашел ту тему, но к сожалению результаты были на картинке, а она не сохранилась.

Так вот. у меня большое сомнение, что повторный сложный динамически меняющийся многотабличный запрос, да еще если с вложенными запросами и попутными вычислениями, будет работать быстрее, чем SQL_CALC_FOUND_ROWS. Ведь дело не в том, что результатом будет COUNT(*). Все равно придется повторно объединять таблицы, делть эти вычисления и так далее. А SQL_CALC_FOUND_ROWS просто дошлепает до конца текущего запроса и выдаст результат. Могу ошибаться конечно, повторные замеры делать лень. Но интуиция подсказывает, что если даже это и медленнее, то не столь значительно для того, чтобы отказаться от интеграции одной строчкой.

Спустя 13 часов, 32 минуты, 25 секунд (15.03.2012 - 00:09) Guest написал(а):
1. Thanks за информацию.
2. Нет, сложный запрос, это допустим составной запрос. Из нескольких таблиц, с применением JOIN, UNION и так далее. В таком запросе невозможно подсчитать к-во строк в таблице. Таблиц то несколько и результат непредсказуем.
Все же с определениями не совсем идеально.
"это допустим составной запрос". Допустим..., значит еще какие-то
варианты сложного запроса имеются? Какие тогда?
2.1 В таком запросе невозможно подсчитать к-во строк в таблице
Видимо верно, если UNION использовать.
А если JOIN, то вроде без проблем.
А то что "Таблиц то несколько" мне кажется вообще роли не играет.
Какая разница скажем
SELECT b.id AS bd, b.name_sort AS bs,  b.name AS bn, b.year_begin,
b.year_end,b.name_2, b.music_kind, b.main_rating, b.rating_art,
b.music_kind_2, c.name AS cn
FROM countries AS c, band AS b
WHERE b.id_country = c.id
AND (b.category = 1 OR b.category = 4)
AND year_end is not null
ORDER BY
$sort $sort_asc";

и
SELECT count(*)
FROM countries AS c, band AS b
WHERE b.id_country = c.id
AND (b.category = 1 OR b.category = 4)
AND year_end is not null
ORDER BY
$sort $sort_asc";



Спустя 7 минут, 35 секунд (15.03.2012 - 00:17) Vladimir67 написал(а):
А... извините,
забыл имя-пароль ввести, предыдуший
Guest я был.

Спустя 9 часов, 23 минуты, 3 секунды (15.03.2012 - 09:40) twin написал(а):
Vladimir67
Рзница в том, что придется выполнять два запроса. И большой разницы нет, получаем мы количество строк каунтом или значения полей. Запрос все равно должен выполниться. В случае с SQL_CALC_FOUND_ROWS сложный запрос выполняется один раз. Просто результат выдается по уровню лимита, а сам запрос продолжает выполняться полностью, пока не пройдет все строки. И потом мы вытаскиваем количество. Насколько я помню, это быстрее, чем второй запрос с каунтом.

Другой вопрос, что для подсчета строк можно использовать другой, более легкий запрос. Но это оправдано тогда, когда складывается ряд обстоятельств. Допустим огромные таблицы, тяжелые запросы, высокие нагрузки и достаточная квалификация программиста. В остальных случаях, а их наверняка больше 90% этим приростом скорости можно спокойно пренебречь в пользу простоты интеграции скрипта. А ставка делалась именно на это. Чтобы любой начинающий программист мог не мудрствуя лукаво двумя-тремя строчками внедрить пагинатор в действующую систему.

Спустя 12 часов, 47 минут, 18 секунд (15.03.2012 - 22:27) Vladimir67 написал(а):
1. Ну, теперь, вроде, понятно...,но,
2. Возникла следующая мысля.
Сделали основной запрос, без лимитов, все равно какой-
простой, сложный, сверхсложный...
В результате есть таблица результатов.
Можно ведь теперь просто средствами PHP
посчитать кол-во строк, то есть получить тот же результат,
который дает нам COUNT(*) и в базу понятно никакая собака не лезет,
чтобы SQL_CALC_FOUND_ROWS или COUNT(*) использовать.
Что здесь не так?
3. Могу ли я (в смысле имею право) использовать данный пагинатор,
с небольшими изменениями на своем личном сайте (рок-музыка)?
Вроде усе, спасибо.

Спустя 4 минуты, 49 секунд (15.03.2012 - 22:32) Vladimir67 написал(а):
Akuchkovsky
Цитата (Vladimir67 @ 15.03.2012 - 03:17)
Век живи, век учись, и все без толку
smile.gif
А улыбаетесь зря, так оно и есть, особенно
если возвыситься на флософский уровень

Спустя 7 часов, 29 минут, 56 секунд (16.03.2012 - 06:02) twin написал(а):
Цитата (Vladimir67 @ 15.03.2012 - 19:27)
Сделали основной запрос, без лимитов, все равно какой-
простой, сложный, сверхсложный...
В результате есть таблица результатов.
Можно ведь теперь просто средствами PHP
посчитать кол-во строк, то есть получить тот же результат,
который дает нам COUNT(*) и в базу понятно никакая собака не лезет,
чтобы SQL_CALC_FOUND_ROWS или COUNT(*) использовать.
Что здесь не так?

Ну а если таблица весит несколько гигов, её всю целиком в пыху тащить? А где набрать столько оперативки?

Цитата
Могу ли я (в смысле имею право) использовать данный пагинатор,
с небольшими изменениями на своем личном сайте (рок-музыка)?
Разумеется. Для того и висит.

Спустя 17 часов, 48 минут, 3 секунды (16.03.2012 - 23:50) Vladimir67 написал(а):
Хм...
Ну а если таблица весит несколько гигов, её всю целиком в пыху тащить? А где набрать столько оперативки?

1. В моем PC 4 ГБ.
Я полагал, что на сервере (приличном) сейчас проблемы
с опер. памятью практически отсуствуют.
2. Данные из базы берутся (речь о PHP, разумеется),
чтобы далее клиентам через браузер выдать.
Какой же разработчик будет десятки, сотни тысяч строк
в одном запросе на юзера вываливать?
3. Спасибо за пагинатор-класс,
как руки дойдут, всобачу в сайт (кое-как доделываю),
потом похвастаюсь.....

Спустя 4 минуты, 24 секунды (16.03.2012 - 23:55) Vladimir67 написал(а):
Цитата (akuchkovsky @ 16.03.2012 - 02:21)
Vladimir67
Во всем есть толк!

Черт знает, может быть,
опять же, если философски подходить.

Спустя 1 день, 23 часа, 15 минут, 50 секунд (18.03.2012 - 23:10) Vladimir67 написал(а):
Twin
Надеюсь просто тупая описка здесь
/**
* Constructor
*
@param int $page
*
@param int $rows
*
@param int $columns
*/

public function __construct($page = 1, $rows = 1, $columns = 1)
{
if($rows > 1)
$this->NumPage = (int)$page;

if($rows > 1)
$this->NumRows = $rows;

if($columns > 1)
$this->NumColumns = $columns;


}

В первой строчке должно быть
 if($page > 1)
$this->NumPage = (int)$page;

Спустя 17 минут, 2 секунды (18.03.2012 - 23:27) Vladimir67 написал(а):
И еще
 public function createLimit()
{

$this->TableTotal = intval(($this->TableCount - $this->NumColumns) / $this->NumRows * $this->NumColumns) - 1;

if($this->NumPage < 1)
$this->NumPage = 1;

if(empty($this->TableTotal) || $this->TableTotal < $this->TableCount)
$this->TableTotal = $this->TableCount;

if($this->NumPage > $this->TableTotal)
$this->NumPage = $this->TableTotal;

$start = $this->NumPage * $this->NumRows * $this->NumColumns - $this->NumRows * $this->NumColumns;

if($start < 0)
$start = 0;

return ' LIMIT '. $start .', '. $this->NumRows * $this->NumColumns;

}

Непонятно, когда вообще может реализоваться условие
 if(empty($this->TableTotal) || $this->TableTotal < $this->TableCount)
$this->TableTotal = $this->TableCount;

Мне кажется его спокойно можно
к чертям собачьим......
Или чего-то не учитываю?


_____________
Век живи, век учись, и все без толку.
Быстрый ответ:

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