Оптимизация функции экспорта
Мне интересно, что было бы лучшим способом ускорить функцию экспорта компании в моем приложении:
function export(){
ini_set('memory_limit', '-1');
ini_set('max_execution_time', 0);
$conditions = $this->getConditions($this->data);
$resultCompanies = $this->Company->find('all', array('conditions' => $conditions));
$this->set(compact('resultCompanies'));
}
Поэтому он ищет компании в базе данных, которые соответствуют определенным условиям. Затем результаты устанавливаются так, чтобы их можно было отображать в соответствующем представлении.
Как я могу ускорить эту функцию? Чем больше результатов вы хотите экспортировать, тем больше времени требуется для их экспорта, но возможно ли каким-то образом их оптимизировать? В настоящее время требуется около 30 секунд, чтобы экспортировать только 4000 результатов - так что я не представляю, что он может экспортировать, скажем, 40000 результатов, и это должно быть в состоянии? Это вопрос сервера?
Благодарю.
1 ответ
Дело не в сервере, а в архитектуре программы.
Вы не хотите извлекать и передавать этот огромный объем информации на лету по очевидным причинам, с которыми вы уже столкнулись.
Я не знаю достаточно о требованиях вашего приложения, но я предполагаю, что вам нужно скачать отчет. Предполагая, что это должно быть всегда актуально, вот что я бы сделал:
Пользователь нажимает на ссылку, чтобы загрузить отчет. Пользователь получит отображаемый индикатор загрузки и готовит сообщение об экспорте отчета с использованием JS и AJAX. На стороне сервера запускается задача для создания отчета.
Фоновая служба, простая оболочка CakePHP, работающая в цикле, заметит, что необходимо создать новый отчет. Он будет создавать отчет, читая записи БД в виде фрагментов, чтобы избежать нехватки памяти, и записывать его в файл. Когда это сделано, запрос на загрузку отчета помечается как выполненный, и файл может быть загружен. На стороне клиента длинный JS-скрипт опроса замечает, что файл готов, и загружает его.
Другое решение, предполагая, что данные не должны быть обновленными, состояло бы в том, чтобы, например, генерировать файлы отчетов один раз в день и предоставлять их для загрузки без какого-либо времени ожидания для пользователя. На стороне сервера задача останется прежней: чтение и запись данных кусками.
О производительности часть вопроса:
Если это не делает его быстрее, но дает пользователю обратную связь, вы даже можете рассчитать (оценить) оставшееся время на основе уже обработанных фрагментов, и, кроме того, это предотвращает сбой сценария из-за нехватки памяти. Вместо записи файла на диск вы можете напрямую передать его клиенту. Как только он начнет читать первый блок, вы начнете отправлять данные. Но, читая данные из базы данных... Ну, бросьте деньги и оборудование на это. Я предлагаю вам что-то вроде массива RAID5 с твердотельными накопителями, если у вас есть деньги. Ожидайте бросить несколько тысяч долларов на это.
Но даже самое быстрое чтение БД ограничено пропускной способностью, которую вы можете отправить и получить пользователю. Для ускорения работы с БД я рекомендую спросить на сайте superuser.com, я не специалист по оборудованию БД, но правильно настроенная конфигурация SSD дает огромный прирост скорости вашей БД.
Получите только те данные, которые вам нужны:
В вашем поиске я не вижу никаких параметров содержимого () или рекурсии: убедитесь, что вы извлекаете только те данные, которые действительно нужны в отчете!