Rails MySQL запутывает время запроса - PullRequest
5 голосов
/ 29 января 2010

У меня есть запрос вычисления количества, который я выполняю тысячи раз в своем приложении Rails, по одному для каждого клиента в БД.

Когда я запускаю запрос в моем клиенте MySQL с отключенным кешем запросов, запрос занимает более 1 мс.

Однако, когда я запускаю свою задачу из консоли Rails с включенным выводом запросов, я заметил, что после первых нескольких очень быстрых запросов время внезапно увеличивается с менее чем 1 мс до примерно 180 мс для оставшихся запросов. .

Я уменьшил innodb_buffer_pool_size, чтобы увидеть изменения в поведении, но ничего не заметил.

Вот вывод с консоли:

  EmailCampaignReport::Open Columns (143.2ms)   SHOW FIELDS FROM `email_campaign_report_opens`
  SQL (0.3ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332330) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333333) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332661) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332326) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332665) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 336027) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333001) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 331983) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332668) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332316) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332325) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 331995) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 334007) 
  SQL (0.2ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333326) 
  SQL (0.1ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332998) 
  SQL (183.9ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 334673) 
  SQL (183.7ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 336751) 
  SQL (183.6ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 333334) 
  SQL (186.3ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332663) 
  SQL (183.7ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332328) 
  SQL (186.3ms)   SELECT count(*) AS count_all FROM `email_campaign_report_opens` WHERE (customer_id = 332659) 

В этой таблице есть столбец customer_id.

Кто-нибудь получил какие-либо предложения относительно того, почему это произойдет?

Спасибо

Ответы [ 4 ]

4 голосов
/ 30 января 2010

Почему бы не выполнить только один запрос?

SELECT customer_id, count(*) AS count_all FROM `email_campaign_report_opens` GROUP BY customer_id;

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

0 голосов
/ 29 января 2010

Какая версия Rails это? В зависимости от вашей версии и вашего кода Ruby / Rails, вы можете кэшировать много данных, не используя их, и через некоторое время он должен выполнить сборку мусора перед получением новых данных, что может объяснить задержку. Заметьте, это предположение.

0 голосов
/ 30 января 2010

Не имеет ли смысла добавить кеш счетчика к ассоциации (читай: добавьте email_campaign_report_opens_count к вашей Customer модели)? Конечно, вы должны инициализировать счетчики во время миграции, но тогда это должно быть очень быстро, и вам даже не нужно прикасаться к связанной таблице при ходьбе по таблице клиентов.

0 голосов
/ 29 января 2010

Это происходит и в вашем приложении rails, или это происходит, когда вы запускаете его в консоли? Кроме того, вы используете клиент, такой как Aptana, или вы запускаете его в оболочке?

...