2012-04-02 5 views
1

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

@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` 

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

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

ответ

1

Почему вы не используете активную запись для этого, а не для 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` 

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

+0

это одно и то же ..... 20-30 секунд, чтобы выполнить запрос .... как я могу использовать команду EXPLAIN над этим запросом? – Dabidi

+0

Добавить .explain в конце запроса (после .first) –

1

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

 @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 
+0

mmm Я не понимаю этого: .sort_by {| x, y | y.created_at <=> x.created_at} Что такое x и y? и как <=> oparator вернуло мне ближайшую запись по дате к параметрам выбранной даты? – Dabidi

+1

Вместо использования sort_by используйте метод сортировки. sort и select - методы массива – Mukesh

Смежные вопросы