Запрос быстрый в MySQL, но медленный при запуске из Rails ActiveRecord - PullRequest
2 голосов
/ 15 февраля 2011

У меня есть запрос, который выполняется очень быстро в консоли MySQL, но очень медленно, когда я запускаю его с помощью Rails Active Record. Это запрос к таблице из 7 миллионов записей:

выберите broker_id, count (abserror), avg (abserror) из fc_estimates где (fpe> '2000-05-28') и (fpe <'2003-06-30') <strong>группировка по broker_id заказ по broker_id;

Это займет 3 минуты.

Затем я запускаю этот запрос в Rails Active Record:

статистика = оценка. выберите ([ "Broker_id", "считать (abserror) как abserror_count", "avg (abserror) as abserror_avg" ]). где (: fpe => ((fpe-1098) .to_date .. (fpe + 30) .to_date)) группа ( "broker_id"). заказ ( "broker_id")

, который генерирует этот sql (вывод из to_sql)

SELECT broker_id, считать (abserror) как abserror_count, avg (abserror) как abserror_avg ОТ fc_estimates ГДЕ (fc_estimates. fpe МЕЖДУ '2000-05-28' И '2003-06-30') GROUP BY broker_id ЗАКАЗАТЬ НА broker_id

и занимает 1 час 40 минут. Возвращает 250 записей.

Я использую Windows 7, MySQl 5.1, Ruby 1.8.7, ActiveRecord 3.04, mysql2 gem 0.2.6

Это таблицы InnoDB, и я увеличил innodb_buffer_pool_size до 480M (что помогло с другими запросами). Одна вещь, которую я наблюдаю, заключается в том, что использование памяти MySQL занимает около 500 МБ, а затем происходит много дисковой активности (перестановка страниц). Что объясняет что-то.

Но, тем не менее, почему у меня такая низкая производительность, когда выполнение одного и того же запроса в консоли MySQL занимает всего 3 минуты? Спасибо за любые идеи или любому, кто испытал подобную ситуацию.

ОБНОВЛЕНИЕ 2011-02-24

Я обновился до MySQL 5.5. Теперь мой запрос в консоли выполняется примерно за 1 мин 40 сек. И использование ActiveRecords занимает около 40 минут.

1 Ответ

1 голос
/ 25 февраля 2011

В вашем коде ruby ​​работает намного больше, чем просто SQL-запрос.Я не Ruby Jedi, но я могу указать на некоторые вещи.

Windows - не лучшее место для работы с МРТ.Возможно, вам стоит попробовать 1.9.2 или JRuby - или даже переключиться на какую-то * nix ОС.

(fpe-1098).to_date..(fpe+30).to_date) создает экземпляр Range для интервалов дат.Возможно, вам следует попробовать другой синтаксис, например: ['fpe > ? AND fpe < ?'(fpe-1098),(fpe+30)] - так будет создано меньше объектов.

Поскольку вы не извлекаете Estimate экземпляров, вместо выполнения запроса с классом модели вы можете передатьSQL генерируется до ActiveRecord::Base.connection.execute.Возможно будет меньше использования памяти и созданных объектов.

...