Rails finder method efficiency question

Consider the following:

anything = WorkoutExercise.find_all_by_exercise_id(params[:id]) if (anything.empty?)   do_something else   do_something_else end

Is the array returned in 'anything' an intelligent proxy to the database? If the result set was a terabyte of data am I in trouble? If so, what should I do?

Thanks,

Cris

Consider the following:

anything = WorkoutExercise.find_all_by_exercise_id(params[:id])

if (anything.empty?)

do_something

else

do_something_else

end

Is the array returned in ‘anything’ an intelligent proxy to the

database?

Any time you call .all, .first or find (including find_all_by_…) you’re actually executing the query and unless you use find_each the entirety of the results will be materialised. The result is an actual array (or an active record object in the case of .first), not a proxy to anything.

If the result set was a terabyte of data am I in trouble? If so, what

should I do?

I’d do something like

if WorkoutExercise.where(:exercise_id =>(params[:id]).exists?

end

assuming you don’t actually need the result set. If you do need to do stuff with the result set, use find_each to process the query in batches.

Fred

Fred,

Thank you.

We tested what you gave =us with ActiveRecord logging to STDOUT and with this code:

   puts 'hi'     e = WorkoutExercise.where(:exercise_id =>(params[:id]))     puts "after"     e.exists?     puts "last one"

We saw this:

hi after   Primary Key (15.0ms) SELECT cc.column_name FROM all_constraints c, all_cons_columns cc WHERE c.owner = 'BROWNBAG' AND c.table_name = 'WORKOUT_EXERCISES' AND c.constraint_type = 'P' AND cc.owner = c.owner AND cc.constraint_name = c.constraint_name   workout_exercises Columns (16.0ms) SELECT column_name AS name, data_type AS sql_type, data_default, nullable, virtual_column, hidden_column, DECODE(data_type, 'NUMBER', data_precision, 'FLOAT', data_precision, 'VARCHAR2', DECODE(char_used, 'C', char_length, data_length), 'RAW', DECODE(char_used, 'C', char_length, data_length), 'CHAR', DECODE(char_used, 'C', char_length, data_length), NULL) AS limit, DECODE(data_type, 'NUMBER', data_scale, NULL) AS scale FROM all_tab_cols WHERE owner = 'BROWNBAG' AND table_name = 'WORKOUT_EXERCISES' AND hidden_column = 'NO' ORDER BY column_id   WorkoutExercise Exists (157.0ms) SELECT 1 AS one FROM "WORKOUT_EXERCISES" WHERE "WORKOUT_EXERCISES"."EXERCISE_ID" = 980190962 AND ROWNUM <= 1 last one

So sure enough the query waits until exists? is called!

Thanks!

Cris