2009-10-15 2 views
0

В настоящее время я бегу что-то похожее на эту команду:Rails: масштабирование с расчетами группы

Person.sum(:cholesterol, :group => :age) 

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

SELECT sum(`people`.cholesterol) AS sum_cholesterol, age AS age 
FROM `people` 
GROUP BY age 

занимает около 0,02 секунды на том же количестве тысяч записей. Как только у меня есть данные, мне не нужно делать больше, чем отображать его. Есть ли более эффективный способ сделать это? Я знаю, что я могу вручную делать SQL-запросы от моделей и контроллеров, я не знаю, будет ли это жизнеспособным вариантом, поскольку я не нашел четкого способа работы с результатом после запроса.

+0

Ну, если это не тот SQL-запрос, который занимает так много времени, он должен быть чем-то другим. Посмотрите на свой журнал, чтобы узнать, нет ли каких-либо других запросов sql, которые могут быть слишком длинными (или слишком много запросов sql). –

+0

Спасибо, это запрос, который занимает время. Когда я запускаю команду в среде mysql, она почти 1000x так же быстро, как при вызове через рельсы. Действительно ли возможно, что рельсы медленны в этом методе? У меня только проблемы с этим методом. – Evan

ответ

2

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

Попробуйте использовать find_by_sql метод, что-то вроде:

Person.find_by_sql("SELECT sum(`people`.cholesterol) AS sum_cholesterol, age AS age FROM `people` GROUP BY age") 

И посмотреть, сколько это занимает.

Также проверьте свои журналы. Они дали вам много информации о том, где происходит так долго рендеринг.

+0

Да, как я уже упоминал ранее о моих журналах, он запускает ожидаемый SQL-запрос «SELECT sum (...», это ТОЛЬКО, что я вижу, когда происходит эта команда. Ваше решение - это то, поиск, время выполнения в значительной степени то же самое, что и запуск его в среде MySQL. Я до сих пор не знаю, почему именно метод Rails занимает намного больше времени, когда он заканчивается тем, что вызывает тот же самый SQL. – Evan

1

Как вы используете свое приложение?

Журналы могут предоставить вам отличную информацию и с mongrel, в режиме разработки вы увидите запросы sql, выполняемые вашим приложением непосредственно в терминале или в вашем файле журнала, если вы отсоединили дворняжку.

Возможно, рельсы не выполняют запрос, который вы ожидаете?

Вы также можете использовать решение, предложенное Yaraher.

find_by_sql непосредственно выполнить запрос к возвращению вы объект рубин с методами геттерных готовы использовать

result = person.find_by_sql("SELECT sum(`people`.cholesterol) AS sum_cholesterol, age AS age FROM `people` GROUP BY age") 

p result.sum_cholesterol 
1

Вы также можете попробовать:

Person.find(:all, :select => "sum(cholestorol) as 'sum_cholesterol'", :group => "age") 

Это может быть немного чище, но Я не знаю, будет ли это быстрее, чем найти по sql.

+0

Это решение также было очень быстрее, чем Person.sum (: холестерин,: группа =>: возраст) – Evan