Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Разбивка на страницы. Не все так просто.

13
26 сентября 2006 года
RussianSpy
3.0K / / 04.07.2006
Заголовок темы банальный. НО! Не спешите с выводами.

Итак представим себе таблицу pays. В ней есть поля PayID, UserID, GameID, PayType, OrderTime, Sum, isSuccess

Администратор системы заходит в админку и решил просмотреть историю платежей какого-то определенного юзера. Поскольку записей много - надо разбить их на страницы и выводить по 20-25 штук на страницу. Как определить их количество?

Казалось бы ответ напрашивается сам собой: сделать COUNT(*) по условию, разделить на количество записей на страницу и получить в итоге количество страниц.
Но не все так просто. Запрос COUNT(*) занимает времени в 2-2.5 раза больше чем собственно сам запрос на выборку. В итоге получается такая фигня: сама таблица небольшая (примерно 1.2 миллиона записей), просто выборка занимает 0.9 сек, COUNT(*) занимает 1.9 сек.

У кого какие еще будут идеи насчет разбивки на страницы?
P4 2800, 2 Gb RAM, RAID 0+1
FreeBSD 6.1, PHP 5.1.4, PostgreSQL 8.1.2

ЗЫ Заранее хранить счетчики на каждого юзера невозможно тк условия выборки истории платежей могут быть разнообразными
ЗЗЫ Временные таблицы не выход
285
26 сентября 2006 года
Romik
479 / / 24.11.2002
т е разница между двумя запросами:
SELECT count(PayID), * FROM pays where UserID=id order by OrderTime
и
SELECT * FROM pays where UserID=id order by OrderTime
примерно 2-2.5 раза?

Сорри, под рукой нет базы
13
26 сентября 2006 года
RussianSpy
3.0K / / 04.07.2006
COUNT - слабое место БД PostgreSQL

С настройками БД уже колдовал - добился прироста всего в 5-8%
Запрос на самом деле чуть сложнее. Но общую идея я описал.

Только что попробовал околошаманский метод: добавил в таблицу поле counter со значением 1 и количество записей считал не через COUNT(*), а через SUM(counter). Разница есть, но она не настолько велика чтобы перекраивать всю структуру БД
285
26 сентября 2006 года
Romik
479 / / 24.11.2002
Ну ладно, а если добавить поле AmmountOfPays в некую таблицу users, т е у каждого юзера будет свой счётчик платежей?

Если count не выход, вариант с sum вас не устроил, то в любом случае прийдётся делать некий alter table, а потом update.
13
26 сентября 2006 года
RussianSpy
3.0K / / 04.07.2006
Не катит.
Условия выборки разнообразны: в промежутке дат, по объему платежа, по типу и т.д.
285
26 сентября 2006 года
Romik
479 / / 24.11.2002
сэр, а Вы VACUUM ANALYZE делали, перед тем, как юзать вариант с count?
13
26 сентября 2006 года
RussianSpy
3.0K / / 04.07.2006
Мы не только VACUUM ANALYZE делали. Мы четыре часа потратили на колдовство над индексами, на шаманство над настройками сервера, мы делали VACUUM FULL ANALYZE и REINDEX TABLE bla-bla-bla.

Только после того как были исчерпаны все идеи я пришел сюда мучить форум =)
285
26 сентября 2006 года
Romik
479 / / 24.11.2002
тут со стороны поступило гениальное по своей простоте решение
pg_num_rows

Oops, осознал что решение хоть и гениальное, но не верное
13
26 сентября 2006 года
RussianSpy
3.0K / / 04.07.2006
[QUOTE=Romik]тут со стороны поступило гениальное по своей простоте решение
pg_num_rows[/QUOTE]
Была такая идея. А теперь давайте представим что по запросу было выдано 1 650 000 записей.

ЗЫ Кстати при использовании pg_num_rows вместо COUNT(*) время сборки страницы увеличилось примерно на 30%
13
26 сентября 2006 года
RussianSpy
3.0K / / 04.07.2006
В общем оставил все как есть. Когда проект будет закончен и переедет на нормальный сервер тогда и будем думать
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог