выбрать по ближайшей дате - PullRequest
1 голос
/ 02 апреля 2012

У меня проблема с производительностью по этому запросу:

@event = Event.find_by_sql("
    SELECT * FROM `IdeProNew_development`.`events`
    WHERE device_id = #{session[:selected_cam_id]}
    AND data_type = 'image'
    AND created_at BETWEEN CONVERT('#{params[:selected_date].to_time.beginning_of_day}', DATETIME)
    AND CONVERT('#{params[:selected_date].to_time.end_of_day}', DATETIME)
    ORDER BY abs(CONVERT('#{params[:selected_date]}', DATETIME)- created_at) LIMIT 1
").first

Я использую это, чтобы выбрать ближайшее событие по "selected_date" ... это нормально, но очень медленно, потому что сканирует всю таблицу (она очень большая) и сортирует по разнице между выбранной датой и датой создания записи.

Я пытаюсь использовать DATEDIFF так:

@event = Event.find_by_sql("
    SELECT * FROM `IdeProNew_development`.`events`
    WHERE device_id = #{session[:selected_cam_id]}
    AND data_type = 'image' AND created_at
    BETWEEN CONVERT('#{params[:selected_date].to_time.beginning_of_day}', DATETIME)
    AND CONVERT('#{params[:selected_date].to_time.end_of_day}', DATETIME)
    ORDER BY abs(DATEDIFF(CONVERT('#{params[:selected_date]}', DATETIME), created_at)) LIMIT 1
").first`

но это не очень хорошо работает (иногда дает неправильный результат) и тоже медленно.

где моя ошибка? Могу ли я использовать какой-либо тип индексации для быстрого выполнения этого запроса?

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

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

     @event = Event.where(:device_id => session[:selected_cam_id])
     .where(:data_type => 'image').to_a
     .select{|i| i.created_at.to_time >= params[:selected_date].to_time.beginning_of_day 
&& i.created_at.to_time <= params[:selected_date].to_time.end_of_day}
.sort{ |x,y| y.created_at  <=> x.created_at}.first
1 голос
/ 02 апреля 2012

Почему вы не используете для этого активную запись, а не SQL-запрос?Примерно так:

`@event = Event.where(:device_id => session[:selected_cam_id]).
               where(:data_type => 'image').
               where("created_at >= ? AND created_at <= ?",    
                                 params[:selected_date].to_time.beginning_of_day, 
                                 params[:selected_date].to_time.end_of_day).
               order("created_at DESC").first`

Я думаю, что это более эффективно.

...