2009-04-15 3 views
1

Я использую библиотеку PHPExcel, которая, кажется, отлично справляется с работой, но в моем подходе это не так быстро.многомерный массив PHP или несколько запросов к mysql DB

Мне нужно создать файл excel с выделенными листами, данными, формулами и стилями (жирным шрифтом, цветом, границей), и мне потребуется выделение вычислительных ресурсов и времени.
Я думаю, что мой подход не так хорош. Какой должен быть правильный порядок, когда он собирается создать такой файл (excel), используя PHP-код и данные из базы данных mysql.

1) генерировать все листы без формата/стиля, ни формулы, добавление и ДАННЫЕ формулы и стиль
2) генерировать лист за листом с DATAS, добавляя формулы, добавив стиль
3) ....

Лучше иметь все необходимые данные из БД в многомерном массиве и не запрашивать db каждый раз, когда я хочу писать на новый лист?

Я использую двухъядерный процессор и 4 ГБ или оперативную память, и мне требуется около 1 минуты, если Apache не раздавит.

ответ

2
  1. имеет MySQL делать расчеты: Я когда-то оптимизировал отчет, в котором первоначальный разработчик используется петлями для вычисления суммы, скорее, функции SQL суммы, это было так плохо написано, что превышено ограничение по времени для PHP
  2. убедитесь, что ваш расчет SQL оптимизирована достаточно
  3. Calculate затем генерировать контент
1

Запросы базы данных, даже те, которые возвращаются как 30 000 строк, обычно занимают всего лишь часть секунды. С такой обработкой и оперативной памятью это, вероятно, замедляется при IO. Я готов поспорить, что большую часть времени тратится на запись файла (ов).

Это, как говорится, я бы предложил иметь все данные спереди. По крайней мере, вы читаете из памяти. Я не уверен, что MySQL загружает все в память указателем на текущую строку или загружает только текущую строку.

+1

Обычный буферизованный запрос будет загружать весь набор результатов в память. Это связано с тем, что курсор через данные выполняется клиентской библиотекой C, которую вызывает библиотека PHP. – staticsan

1

С минутным временем обработки ваш набор данных не кажется достаточно большим, чтобы требовать разбиения результирующего набора.

Таким образом, с учетом этого, все это будет загружено в память.

Однако mysql кэширует запрос в любом случае, поэтому последовательные повторяющиеся запросы также не должны быть большой проблемой.

Звучит как запись IO в файл на диске - это ваша медленная точка. Я не очень разбираюсь в том, как стили и форматирование работают для файлов xls, но я уверен, что вы могли бы уменьшить массу бессмысленных записей, уменьшив форматирование или упорядочивая его, чтобы вы не делали никаких встроенных форм, если это даже возможное.

Лучшее, что я бы посоветовал, - это оптимизация вашего запроса. Это, как правило, первое оптимизирующее место, которое я смотрю с этим типом проблемы. Если бы вы могли отредактировать свой пост и включить sql, я бы мог посмотреть. (не стесняйтесь обрезать & информацию, относящуюся к полосе)

2

Я бы предложил профилировать ваш код PHP, чтобы узнать, сколько времени потрачено. Вы можете найти a step-by-step tutorial about using XDebug to profile PHP conde в моем блоге. Затем попробуйте оптимизировать детали, которые потребляют наибольшее время/называются наиболее часто. Одна из лучших оптимизаций, которую вы можете сделать, - это заменить PHP-методы встроенными функциями, если это возможно, потому что они на порядок быстрее.

0

MySQL сможет выполнять любые вычисления/преобразования данных, чем ваш уровень PHP, поэтому я бы написал один запрос, который выполняет всю работу, чтобы получить данные для одной электронной таблицы.

Чем это делается для каждой таблицы.

2

Это может быть быстрее, чтобы сделать больше, более простые запросы, чем сделать меньше, более сложные запросы. Но вам нужно сравнивать их, потому что это зависит от данных, которые вы запрашиваете.

Таким образом, вы можете столкнуться с проблемами памяти в PHP. То, что я бы рекомендовал, - это увидеть, можно ли переустановить алгоритм обработки данных. То, к чему я буду работать, - это получить только один большой набор данных за один раз, но уже отсортирован по MySQL в том порядке, в котором вам нужно его обработать. Затем вы можете использовать небуферизованный запрос.

Небуферизованный запрос означает, что клиентская библиотека не будет хранить весь набор результатов перед передачей его вашему коду. Это означает, что он может быть больше, чем обычно обрабатывает библиотека, но для этого ваш цикл обработки должен извлекать строку из API в каждом цикле - то есть это означает, что цикл while() вызывает mysql_fetch_assoc() каждый раз.

Другим преимуществом работы с набором результатов, который уже в том порядке, в котором вы нуждаетесь, является то, что вы можете запросить больше, чем нужно, и отфильтровать его, когда идете. Это работает, когда запрашивается больше, потому что это нет фильтрация по базе данных.

Смежные вопросы