пейджер и 100к записей

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Ответить
Аватара пользователя
because
Сообщения: 689
Зарегистрирован: 2010.09.30, 22:01

пейджер и 100к записей

Сообщение because »

Когда в базе становится много записей и запрос сложный по структуре, 1-2 JOIN, 1-2 LEFT JOIN, нужна сортировка, поиск по названию. То подсчет записей для пейджера через COUNT становится проигрышным - 1сек или >1 секунды. Причем с ростом числа данных, это время будет только расти. Как вы решаете такую проблему ? Пока я вижу только одно решение, отказаться от COUNT и выбирать фиксированный лимит записей, и предлагать пользователю загрузить еще результаты по требованию
RTFM !
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: пейджер и 100к записей

Сообщение slavcodev »

а кеширование не подходит? как часто меняется значение этого count()?
Жду Yii 3!
Аватара пользователя
because
Сообщения: 689
Зарегистрирован: 2010.09.30, 22:01

Re: пейджер и 100к записей

Сообщение because »

в общем-то подходит, только вот как корректно сбрасывать кэш, записи в базу пишутся другим приложением, а на сайте выводятся
кстати, заметил одну интересную вещь, в mysql если кэш включить, то запросы исполняемые в Phpmyadmin кэшируются, а те, что исполняются yii - нет
RTFM !
Аватара пользователя
Svyatov
Сообщения: 459
Зарегистрирован: 2010.08.12, 14:50
Откуда: Санкт-Петербург
Контактная информация:

Re: пейджер и 100к записей

Сообщение Svyatov »

Тюнить БД, пересмотреть структуру таблиц, юзать кэш. 1 секунда при выборке 100К записей явно говорит о какой-то беде в проектировании БД, либо в построенном запросе.
TM123
Сообщения: 608
Зарегистрирован: 2011.06.09, 11:18

Re: пейджер и 100к записей

Сообщение TM123 »

1. Настроить правильно индексы, моя практика увеличивала скорость исполнения запросов до нескольких тысяч раз. Может быть планировщик использует неправильный индекс, тогда указать принудительно, но за последние лет 5 у меня уже таких случаев не было, разве что у вас какая-та очень старая БД.
2. Правильно написать запрос, отказаться от подзапросов, DISTINCT, GROUP BY, ORDER BY, LEFT JOIN. По моей практике, если стоит выбор DISTINCT или GROUP BY, последний предпочтительнее, судя по всему он работает с максимальным использованием индексов, а первый полностью выполняется силами процессора, но запрос с GROUP BY сложнее и дольше писать, но тут опять таки все зависит от реализации базы данных, у нормальной разницы быть не должно, но реальность на много хуже.
3. Правильно настроить распределение памяти на сервере базы данных, добившись того, чтобы больше данных хранилось в кэше памяти и меньше было обращений к диску
4. Закэшировать, на сколько важно получение данных в реальном времени, если вы поставите кэш 60 или 30 секунд, думаю на прикладной функциональности не очень скажется, если вы допускаете запрос дополнительных данных по запросу. С другой стороны количество запросов сильно снизится и параллельные запросы не будут тормозить друг друга, что может увеличить скорость исполнения запроса подготавливающего кэш. Сам кэш особо терзать не надо, просто при запросе данных пишете что их надо закэшировать, а YII должен сам разобраться, если есть кэш то взять их из кэша, если нет то сформировать его. Протухание данных автоматически обрабатывается кэширующей системой.
5. Переделать структуру базы данных, сделать ее более эффективной или уменьшить уровень нормализации для уменьшения количества JOIN. Обычно в качестве ключей используют INT поля, как это не выглядет смешно, но часто при замене ключа на VARCHAR, скорость работы базы может увеличится за счет отказа от JOIN. Например, у вас есть таблица справочника и вам требуется найти по названию из нее набор записей из другой таблицы. В классическом рекомендуемом варианте придется сделать JOIN чтобы найти список справочных значений удовлетворяющих в названии и потом выбирать данные из основной таблицы. Если ключ заменить на это самое название, то можно отказаться от JOIN, есть нюанс, если при поиске по названию использовать LIKE, то все наоборот замедлится. В общем суть в том, что выбрать по индексу быстрее, чем сделать JOIN (требует лишних дисковых операций) и потом выбрать по индексу, но тут еще очень зависит от реализации механизма JOIN в конкретной БД, ну и размер базы вырастет.
6. Увеличить железо сервера базы данных, в первую очередь память, потом диски, установить RAID, процессор стоит наращивать только если в тормозящих запросах идет большое количество математических вычислений.
7. Построить кластер

Моя многолетняя практика состоит в основном из 1, 2 и 3, остальное применял редко, 7 никогда.
Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: пейджер и 100к записей

Сообщение timlar »

Svyatov писал(а):Тюнить БД, пересмотреть структуру таблиц, юзать кэш. 1 секунда при выборке 100К записей явно говорит о какой-то беде в проектировании БД, либо в построенном запросе.
Полностью согласен. Недавно на одной из рабочих станций установил Убунту. Запустил копию проекта, заметил, что долго выполняются запросы. Начал разбираться. Сделал простейший цикл который выбирал из базы 100к записей. Работа скрипта оборвалась по таймауту. Снизил количество запросов до 10к, скрипт выполнился, но секунд за 10. Начал тюнинговать mysql (у меня таблицы InnoDB). В результате шаманства скорость выборки 100к записей упала до 0.000хх с.
Twitter: @timlar_ua
Ответить