2010-04-10 61 views
4

我有一個包含約49403459記錄的表。如何優化在日期的where子句中具有to_char的Oracle查詢

我想查詢日期範圍內的表格。說04/10/201004/10/2010。但是,日期以格式10-APR-10 10.15.06.000000 AM(時間戳)存儲在表中。

,當我做

SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE TO_CHAR (create_date,'MM/DD/YYYY)' >= '04/10/2010' 
AND TO_CHAR (create_date, 'MM/DD/YYYY' <= '04/10/2010' 

我得到529行,但在255.59秒的成績!這是因爲我想我正在做每個記錄上的TO_CHAR。

然而,當我做

SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE create_date >= to_date('04/10/2010','MM/DD/YYYY') 
AND create_date <= to_date('04/10/2010','MM/DD/YYYY') 

然後我得到0結果0.14秒。

如何快速查詢此查詢並仍然有效(529)結果?

在這一點上我不能改變索引。現在我認爲索引創建在create_date列。

如何將兩個日期範圍轉換爲第一個日期範圍轉換爲全部爲0的時間戳,並將第二個日期範圍轉換爲日期的最後時間戳時間戳。如果這是有道理的...?

where子句取沒有結果以下兩種:

WHERE    
create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
create_date <= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 

回答

2

在第一個查詢,你正在做一個字符比較,而不是一個日期比較,這不應該產生正確的結果。

例如,使用你的邏輯,01/02/2009將大於01/01/2010因爲天組件「02」是比天還組件「01」比較時,人物和年度將永遠不會被評價更高。

+0

謝謝。我嘗試過,但仍然沒有得到任何結果。請參閱我的編輯 – Josh 2010-04-10 18:41:50

+0

我編輯了我的答案。我認爲你的第二個查詢可能是正確的。第一個查詢給你不正確的結果。 – newdayrising 2010-04-10 18:43:44

+0

不......我可以查詢表格並查看是否有今天創建的記錄。 .. – Josh 2010-04-10 18:46:19

2

這工作:

WHERE    
create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
create_date <= to_timestamp('04/10/2010 23:59:59:123000','MM/DD/YYYY HH24:MI:SS.FF') 
1
SELECT bunch,of,stuff,create_date 
    FROM myTable 
WHERE create_date >= to_date('04/10/2010','MM/DD/YYYY') 
    AND create_date < to_date('04/11/2010','MM/DD/YYYY') 

日期04/10/2010包括從半夜10日的所有日期的值,直到下午11:59:59,所以讓一切小於11將覆蓋所有的基地。另一種方法是確保myTable中的數據在數據輸入時截斷了CREATE_DATE字段;我更喜歡爲DATE字段做這件事,如果我關心時間組件,我使用TIMESTAMPs。

3

當然,這並不工作:

WHERE    
    create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
    create_date <= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 

因爲這隻會返回行,其中CREATE_DATE是2010年4月10日12:00 AM 正是

如果你想獲得其中CREATE_DATE發生的任何時間對2010年4月10日當天的所有行,使用:

WHERE    
    create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
    create_date < to_timestamp('04/11/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 

或者如果你喜歡:

WHERE create_date BETWEEN to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
         AND to_timestamp('04/10/2010 23:59:59.999999','MM/DD/YYYY HH24:MI:SS.FF') 

由方式,當你想要表示午夜時,你可以把所有其他部分留下。所以,你可以只說:

WHERE    
    create_date >= to_timestamp('04/10/2010','MM/DD/YYYY') 
AND 
    create_date < to_timestamp('04/11/2010','MM/DD/YYYY') 
4

我得到529行,但在255.59秒! 這是因爲我想我正在做每個記錄上的TO_CHAR 。

如果你要generate an execution plan你的第一個查詢...

explain plan for 
SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE TO_CHAR (create_date,'MM/DD/YYYY)' >= '04/10/2010' 
AND TO_CHAR (create_date, 'MM/DD/YYYY') <= '04/10/2010' 
/

...你會看到它做了全表掃描。這是因爲to_char()阻止在CREATE DATE上使用您的索引。

你不說花費了多少時間,當你跑到返回結果...

SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE    
create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
create_date <= to_timestamp('04/10/2010 23:59:59:123000','MM/DD/YYYY HH24:MI:SS.FF') 
/

...但我希望它是方式4分鐘內接近0.14秒。

0

您的第一個查詢正在進行字符串比較,結果錯誤。 你的第二查詢需要是:

WHERE CREATE_DATE> = TRUNC(TO_DATE('04/10/2010' , 'MM/DD/YYYY'))

或添加HH :mi:ss給謂詞。這不是簡單的工作,因爲你用不同的方式格式化日期以達到Oracle的期望。