пейджер и 100к записей
пейджер и 100к записей
Когда в базе становится много записей и запрос сложный по структуре, 1-2 JOIN, 1-2 LEFT JOIN, нужна сортировка, поиск по названию. То подсчет записей для пейджера через COUNT становится проигрышным - 1сек или >1 секунды. Причем с ростом числа данных, это время будет только расти. Как вы решаете такую проблему ? Пока я вижу только одно решение, отказаться от COUNT и выбирать фиксированный лимит записей, и предлагать пользователю загрузить еще результаты по требованию
RTFM !
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: пейджер и 100к записей
а кеширование не подходит? как часто меняется значение этого count()?
Жду Yii 3!
Re: пейджер и 100к записей
в общем-то подходит, только вот как корректно сбрасывать кэш, записи в базу пишутся другим приложением, а на сайте выводятся
кстати, заметил одну интересную вещь, в mysql если кэш включить, то запросы исполняемые в Phpmyadmin кэшируются, а те, что исполняются yii - нет
кстати, заметил одну интересную вещь, в mysql если кэш включить, то запросы исполняемые в Phpmyadmin кэшируются, а те, что исполняются yii - нет
RTFM !
- Svyatov
- Сообщения: 459
- Зарегистрирован: 2010.08.12, 14:50
- Откуда: Санкт-Петербург
- Контактная информация:
Re: пейджер и 100к записей
Тюнить БД, пересмотреть структуру таблиц, юзать кэш. 1 секунда при выборке 100К записей явно говорит о какой-то беде в проектировании БД, либо в построенном запросе.
Re: пейджер и 100к записей
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 никогда.
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к записей
Полностью согласен. Недавно на одной из рабочих станций установил Убунту. Запустил копию проекта, заметил, что долго выполняются запросы. Начал разбираться. Сделал простейший цикл который выбирал из базы 100к записей. Работа скрипта оборвалась по таймауту. Снизил количество запросов до 10к, скрипт выполнился, но секунд за 10. Начал тюнинговать mysql (у меня таблицы InnoDB). В результате шаманства скорость выборки 100к записей упала до 0.000хх с.Svyatov писал(а):Тюнить БД, пересмотреть структуру таблиц, юзать кэш. 1 секунда при выборке 100К записей явно говорит о какой-то беде в проектировании БД, либо в построенном запросе.
Twitter: @timlar_ua