Стал смотреть пагинатор от 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 - спасибо, я так бы и не узнал про существование такой возможности в этом классе, век живи век учись(!) ![]() |
twin, ты на меня не злись только, но уж больно формулировка "Сложные запросы" непонятна. А еще для развития учеников полезно было бы написать, почему SQL_CALC_FOUND_ROWS медленнее бывает. Тогда формулировка "Сложные запросы" сама уйдет

Спустя 2 часа, 57 минут, 48 секунд (13.03.2012 - 20:27) twin написал(а):
Цитата (glock18 @ 13.03.2012 - 14:29) | ||
twin, ты на меня не злись только, но уж больно формулировка "Сложные запросы" непонятна. А еще для развития учеников полезно было бы написать, почему SQL_CALC_FOUND_ROWS медленнее бывает. Тогда формулировка "Сложные запросы" сама уйдет ![]() |
Вась, привет. Ты о чем, как можно злиться))) Если бы не твои советы и не наши споры, я бы наверно долго еще бы буксовал. А пагинатор у меня на старом сайте, я его почти не поддерживаю. Хотя нужно обновить, там куча ляпов. Время бы найти)))
Спустя 2 часа, 46 минут, 26 секунд (13.03.2012 - 23:14) glock18 написал(а):
Цитата (twin @ 13.03.2012 - 17:27) | ||||
Вась, привет. Ты о чем, как можно злиться))) Если бы не твои советы и не наши споры, я бы наверно долго еще бы буксовал. А пагинатор у меня на старом сайте, я его почти не поддерживаю. Хотя нужно обновить, там куча ляпов. Время бы найти))) |
да, дискуссии пылкие были, что и говорить

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


Спустя 26 минут, 36 секунд (13.03.2012 - 23:40) Vladimir67 написал(а):
Да....
1. Спасибо.
2. Прочитал, но..., возможно мало виски выпил...
Во второй функции пример, надо полагать, сложного запроса.
И что такое не сложный запрос, где нет условий выборки?... (WHERE....)?
Если я буду обрабатывать этот запрос первой функцией,
что не сработает?
Там стоит
Мне кажется, что в $table[1] будет стоять
`table` WHERE `text` LIKE '%2%.
И функцию SELECT SQL_CALC_FOUND_ROWS
с успехом выполнит обычный COUNT(*).
Где ошибка в моих рассуждениях?
То есть пока не понимаю - на черта эта вторая функция????
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.
Еще по ходу вопрос.
Это во второй функции.
Почему preg_replace используется,
а не substr_replace(), то есть зачем из пушки по воробьям...?
Еще по ходу вопрос.
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, ты серьезно что ли?

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

Вообще говоря единственное место, где я бы его мог посоветовать использовать - запросы на одну таблицу с условиями выборки, не покрытыми индексами. Хотя как по мне, то лучше покрыть их индексами и выбирать каунтом
Спустя 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 - только то, что они есть.
вот цитата по ссылке, которая в купе с твоим определением сложного запроса несколько не стыкуется
Цитата |
Когда потребуется отлистать результаты сложного запроса, вместо метода countQuery() нужно вызвать метод calcQuery() и все будет чики-пики. |
Вообще если позволишь, я заметил уже давно, что у тебя в курсах есть нераскрытые понятия, и вот конкретно в этом случае получается, что обычное значение понятия не стыкуется с реальностью в плане использования SQL_CALC_FOUND_ROWS.
Я бы посоветовал вам в будущем все же в уроках определения писать, или же ввести глоссарий. Поскольку, у вас, раньше по крайней мере, было много полных новичков, они все это на веру воспринимают, и может получиться немного поповский эффект, когда ввиду авторитета учителя, ученики его уверены в его словах больше, чем в себе самих

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

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


Спустя 27 минут, 5 секунд (14.03.2012 - 10:37) twin написал(а):
glock18
Ну я помню нашу бталию на этот счет. Тут два момента. Я делал упор на простоту интеграции раз и касаемо сложных запросов и каунта ты меня тогд не убедил. Я потому и делал замеры. Я нашел ту тему, но к сожалению результаты были на картинке, а она не сохранилась.
Так вот. у меня большое сомнение, что повторный сложный динамически меняющийся многотабличный запрос, да еще если с вложенными запросами и попутными вычислениями, будет работать быстрее, чем SQL_CALC_FOUND_ROWS. Ведь дело не в том, что результатом будет COUNT(*). Все равно придется повторно объединять таблицы, делть эти вычисления и так далее. А SQL_CALC_FOUND_ROWS просто дошлепает до конца текущего запроса и выдаст результат. Могу ошибаться конечно, повторные замеры делать лень. Но интуиция подсказывает, что если даже это и медленнее, то не столь значительно для того, чтобы отказаться от интеграции одной строчкой.
Ну я помню нашу бталию на этот счет. Тут два момента. Я делал упор на простоту интеграции раз и касаемо сложных запросов и каунта ты меня тогд не убедил. Я потому и делал замеры. Я нашел ту тему, но к сожалению результаты были на картинке, а она не сохранилась.
Так вот. у меня большое сомнение, что повторный сложный динамически меняющийся многотабличный запрос, да еще если с вложенными запросами и попутными вычислениями, будет работать быстрее, чем 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, то вроде без проблем.
А то что "Таблиц то несколько" мне кажется вообще роли не играет.
Какая разница скажем
и
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 я был.
забыл имя-пароль ввести, предыдуший
Guest я был.
Спустя 9 часов, 23 минуты, 3 секунды (15.03.2012 - 09:40) twin написал(а):
Vladimir67
Рзница в том, что придется выполнять два запроса. И большой разницы нет, получаем мы количество строк каунтом или значения полей. Запрос все равно должен выполниться. В случае с SQL_CALC_FOUND_ROWS сложный запрос выполняется один раз. Просто результат выдается по уровню лимита, а сам запрос продолжает выполняться полностью, пока не пройдет все строки. И потом мы вытаскиваем количество. Насколько я помню, это быстрее, чем второй запрос с каунтом.
Другой вопрос, что для подсчета строк можно использовать другой, более легкий запрос. Но это оправдано тогда, когда складывается ряд обстоятельств. Допустим огромные таблицы, тяжелые запросы, высокие нагрузки и достаточная квалификация программиста. В остальных случаях, а их наверняка больше 90% этим приростом скорости можно спокойно пренебречь в пользу простоты интеграции скрипта. А ставка делалась именно на это. Чтобы любой начинающий программист мог не мудрствуя лукаво двумя-тремя строчками внедрить пагинатор в действующую систему.
Рзница в том, что придется выполнять два запроса. И большой разницы нет, получаем мы количество строк каунтом или значения полей. Запрос все равно должен выполниться. В случае с SQL_CALC_FOUND_ROWS сложный запрос выполняется один раз. Просто результат выдается по уровню лимита, а сам запрос продолжает выполняться полностью, пока не пройдет все строки. И потом мы вытаскиваем количество. Насколько я помню, это быстрее, чем второй запрос с каунтом.
Другой вопрос, что для подсчета строк можно использовать другой, более легкий запрос. Но это оправдано тогда, когда складывается ряд обстоятельств. Допустим огромные таблицы, тяжелые запросы, высокие нагрузки и достаточная квалификация программиста. В остальных случаях, а их наверняка больше 90% этим приростом скорости можно спокойно пренебречь в пользу простоты интеграции скрипта. А ставка делалась именно на это. Чтобы любой начинающий программист мог не мудрствуя лукаво двумя-тремя строчками внедрить пагинатор в действующую систему.
Спустя 12 часов, 47 минут, 18 секунд (15.03.2012 - 22:27) Vladimir67 написал(а):
1. Ну, теперь, вроде, понятно...,но,
2. Возникла следующая мысля.
Сделали основной запрос, без лимитов, все равно какой-
простой, сложный, сверхсложный...
В результате есть таблица результатов.
Можно ведь теперь просто средствами PHP
посчитать кол-во строк, то есть получить тот же результат,
который дает нам COUNT(*) и в базу понятно никакая собака не лезет,
чтобы SQL_CALC_FOUND_ROWS или COUNT(*) использовать.
Что здесь не так?
3. Могу ли я (в смысле имею право) использовать данный пагинатор,
с небольшими изменениями на своем личном сайте (рок-музыка)?
Вроде усе, спасибо.
2. Возникла следующая мысля.
Сделали основной запрос, без лимитов, все равно какой-
простой, сложный, сверхсложный...
В результате есть таблица результатов.
Можно ведь теперь просто средствами PHP
посчитать кол-во строк, то есть получить тот же результат,
который дает нам COUNT(*) и в базу понятно никакая собака не лезет,
чтобы SQL_CALC_FOUND_ROWS или COUNT(*) использовать.
Что здесь не так?
3. Могу ли я (в смысле имею право) использовать данный пагинатор,
с небольшими изменениями на своем личном сайте (рок-музыка)?
Вроде усе, спасибо.
Спустя 4 минуты, 49 секунд (15.03.2012 - 22:32) Vladimir67 написал(а):
Akuchkovsky
Цитата (Vladimir67 @ 15.03.2012 - 03:17) |
Век живи, век учись, и все без толку |

А улыбаетесь зря, так оно и есть, особенно
если возвыситься на флософский уровень
Спустя 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. Спасибо за пагинатор-класс,
как руки дойдут, всобачу в сайт (кое-как доделываю),
потом похвастаюсь.....
Ну а если таблица весит несколько гигов, её всю целиком в пыху тащить? А где набрать столько оперативки?
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;
Мне кажется его спокойно можно
к чертям собачьим......
Или чего-то не учитываю?
_____________
Век живи, век учись, и все без толку.