2013-05-21 2 views
0

Я знаю, что это было предложено до, по крайней мере в этой теме: is php sort better than mysql "order by"?Performance - заказ на в MySQL или PHP

Однако, я все еще не уверен насчет правильного выбора здесь, так как производительность на делает сортировка на стороне PHP почти в 40 раз быстрее. Этот запрос MySQL работает примерно 350-400ms

SELECT 
keywords as id, 
SUM(impressions) as impressions, 
SUM(clicks) as clicks, 
SUM(conversions) as conversions, 
SUM(not_ctr) as not_ctr, 
SUM(revenue) as revenue, 
SUM(cost) as cost 
FROM visits WHERE campaign_id = 104 GROUP BY keywords(it's an integer) DESC 

Ключевые слова и CAMPAIGN_ID столбцы индексируются.

Использование приблизительно 150 тыс. Строк и возвращает около 1500 строк. Результаты затем пересчитываются (мы вычисляем ставки кликов, коэффициенты конверсии, ROI и т. Д., А также итоговые значения для всего набора результатов). Расчеты выполняются в PHP.

Теперь моя идея состояла в том, чтобы сохранить результаты с помощью PHP APC для быстрого извлечения, однако мы должны иметь возможность заказывать эти результаты по столбцам, а также рассчитанные значения, поэтому, если бы я хотел заказать по кликам Мне пришлось бы использовать (SUM(clicks)/(SUM(impressions) - SUM(not_ctr)) в запросе, который делает его примерно на 40 мс медленнее, а начальные 400 мс уже давно.

Кроме того, мы разбиваем эти результаты, но добавление LIMIT 0,200 не влияет на производительность.

При тестировании подхода APC я выполнил запрос, выполнил дополнительные вычисления и сохранил массив в памяти, чтобы он выполнялся только один раз во время первоначального запроса и работал как шарм. Извлечение и сортировка массива из памяти занимали всего около 10 мс, однако использование памяти сценария было около 25 МБ. Может быть, стоит загрузить результаты в таблицу памяти, а затем напрямую запросить эту таблицу?

Все это делается на моей локальной машине (i7, 8gb ram), которая имеет установку по умолчанию MySQL, а производственный сервер - это 512 МБ на Rackspace, на котором я еще не тестировал, поэтому, если возможно, игнорировать настройку сервера ,

Итак, реальный вопрос: стоит ли использовать таблицы памяти или я должен просто использовать сортировку PHP и игнорировать использование ОЗУ, так как я всегда могу обновить ОЗУ? Какие еще варианты вы могли бы рассмотреть при оптимизации производительности?

+0

Возможно, вы захотите рассмотреть вопрос о разбиении запроса на подзапросы [Документация] (http://dev.mysql.com/doc/refman/5.0/en/subqueries.html). Я считаю, что это позволит вам получить сначала данные, затем суммируют и упорядочивают. общая идея состоит в том, чтобы разбить ваш запрос на более мелкие части, которые работают быстрее. – Dropzilla

+0

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

+0

Базовые настройки MySQL хороши для ПК с 10-12 годами. Попробуйте различные конфигурации (установите больше памяти, CPU на разные настройки) и движок хранения INNODB, если вы этого не пробовали. –

ответ

1

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

Мне интересно, помогут ли вам индексы. Я рекомендую вам попробовать запрос:

  1. без индексов
  2. с индексом только на campaign_id
  3. С обоих индексов

Индексы не всегда полезны. Один особенно важный фактор называется «избирательность». Если в таблице есть только две кампании, то вам, вероятно, лучше делать сканирование полного стола, а не косвенно искать индекс. Это потому что особенно важно, когда таблица не вписывается в память (в результате возникает условие, когда каждая строка требует загрузки страницы в кеш).

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

+0

Хм .. хорошо ответить, что есть несколько тысяч кампаний и растет. Однако эта конкретная кампания содержит почти половину данных по отношению к ней. Мы переключимся на memcached, как только нам потребуется несколько серверов для балансировки нагрузки. – Ignas