2011-05-13 101 views
0

我在查詢時遇到了很多麻煩。我真的不知道如何解釋這一點,但我會嘗試。查詢日期時間範圍,同時考慮到時區

基本上,我們有幾個對象帶有'posted_at'字段,用於在日期時間字段中保存日期和時間以及時區。我需要查詢和獲取這些對象的日期範圍。

以前,我將它轉換爲Date並將它與另一個Date對象進行比較。查詢是這樣的:

Date(posted_at) >= :start_date AND Date(posted_at) <= :end_date 

然而,當Postgre它轉換爲日期,就失去了造成不準確的效果在查詢時區信息。

於是,我改變了這個:

if start_date then 
    start_time = Time.zone.parse("#{start_date.year}-#{start_date.month}-#{start_date.day}") 
    conditions << "posted_at >= :start" 
    hash[:start] = start_time 
end 

if end_date then 
    end_time = Time.zone.parse("#{end_date.year}-#{end_date.month}-#{end_date.day}").end_of_day 
    conditions << "posted_at <= :end" 
    hash[:end] = end_time 
end 

雖然這讓我準確的結果,它也有可怕的性能,並導致一些超時在我的應用程序。

我找不到任何其他方式來做這個查詢,仍然保持準確的結果。會有人有一些建議或想法?

預先感謝您。

回答

1

你永遠不想在你的數據庫中存儲時區信息。

以下是討論一些缺陷讀:

http://derickrethans.nl/storing-date-time-in-database.html

你會得到更好的結果tadman提示:您的時間戳at time zone 'utc'添加一個新的領域,並建立索引。然後你可以使用posted_at between ? and ?來獲取東西。

+0

非常感謝Denis,值得了解。 – MarceloJ 2011-05-17 19:47:34

0

您可能會有更多的運氣將您的開始和結束時間轉換爲UTC,這使得時區在進行查詢本身時往往無關緊要。這樣做是很輕鬆了:

start_date.to_time.to_datetime.beginning_of_day.utc 
end_date.to_time.to_datetime.end_of_day.utc 

您也可以調整您的查詢是:

posted_at BETWEEN :start AND :end 

一定要對字段您正在搜索的索引,也或者你會得到可怕性能。

+0

該字段已編入索引,我試過這兩種方法。仍然得到一些超時,但:( – MarceloJ 2011-05-13 19:19:55

+0

它在'log/development.log'中產生了什麼查詢?你有沒有試過在這個查詢中使用'EXAMINE'?它通常會突出顯示哪裏可能有問題 – tadman 2011-05-16 14:32:45

+0

我認爲問題是'實際上是查詢,但事實是我們有數百萬行......因爲當我比較日期時,所有事情都正常工作,我在這裏與一些人交談,我們將創建一個新的索引列,以保留日期,考慮到時區感謝您的幫助和信息 – MarceloJ 2011-05-17 19:44:03