2012-03-26 79 views
2

首先,描述我的問題的一個簡單示例。使用Nhibernate將Oracle日期映射到日期時間3.2

型號

public class User 
{ 
    public virtual String UserID { get; set; } 
    public virtual String UserName { get; set; } 
    public virtual DateTime LastLoginTime { get; set; } 
} 

映射

<id name="UserID" type="AnsiString"> 
    <column name="p_UserID_vc" length="20"></column> 
    <generator class="assigned"/> 
</id> 
<property name="UserName" column="UserName_vc" type="AnsiString"> 
<property name="LastLoginTime" column="LastLoginTime_d" type="DateTime"> 

create table T_User 
(
    p_userid_vc   VARCHAR2(20) not null, 
    username_vc   VARCHAR2(50), 
    lastlogintime_d  DATE, 
) 

現在,有在這個表中的一個億的用戶。我在LastLoginTime中創建一個oracle索引。我用這樣的查詢:

var list = Responsity<User>.Where(q => q.LastLoginTime <= DateTime.Now && 
      q.LastLoginTime >= DateTime.Now.AddDays(-7));   

我使用NHibernate的個人資料WATCHOUT真正的SQL字符串:

select t.p_UserID_vc 
    from T_User t 
where t.lastlogintime_d >= TIMESTAMP '2012-03-19 16:58:32.00' /* :p1 */ 
    and t.lastlogintime_d <= TIMESTAMP '2012-03-26 16:58:32.00' /* :p2 */ 

它沒有使用索引。我認爲它應該使用'to_date',以便它可以使用索引。如何配置映射文件?

+0

沒有'LastLoginTime'在你的表格定義。它是什麼類型? 'DATE'或'TIMESTAMP'? – 2012-03-26 04:33:36

+0

對不起,我編輯過。 LastLoginTime的DBType是DATE.I認爲Nhibernate會使用'to_date'而不是'TIMESTAMP',但它沒有。 – 2012-03-26 05:56:06

回答

3

有幾個原因,它可能不使用索引:

  1. LastLoginTime的數據類型是一個DATE,但參數是TIMESTAMP S,所以它可能列被隱式轉換爲時間戳,這意味着它不能使用索引。

  2. 基於成本的優化器(CBO)可能使用的統計信息表明使用索引的效率會低於不使用它。例如,表中可能只有很少的行,或者直方圖可能會告訴CBO,大量的行與您查詢的日期範圍相匹配。全表掃描超越使用索引的查詢並不罕見。

  3. 也許表上的統計資料已經過時,導致CBO做出不準確的估計。

對您的查詢做一個解釋計劃,以確定原因是什麼。

注意:使用文字值的查詢(例如TIMESTAMP '...')的計劃可能與使用綁定變量的查詢(例如p1p2)的計劃完全不同。爲實際正在執行的查詢運行解釋計劃。

+0

您的第一個原因是正確的。LastLoginTime的DbType是DATE.I將DateTime發送到Nhibernate,但它將參數轉換爲TimeStamp.so,數據庫無法使用索引。如何修改要發送的配置文件DateTime直接? – 2012-03-26 06:11:40

+0

我不知道如何配置NHibernate,對不起,但你想要的是它使用'TO_DATE('2012-03-19 16:58:32','YYYY-MM-DD HH24:MI: SS')'... – 2012-03-28 03:05:09

+0

終於,我發現了這篇文章的真正原因(https://forums.oracle.com/forums/thread.jspa?messageID=1659839)。它是通過發送帶有DateTime類型參數的參數化查詢引起的。將參數更改爲TimeStamp而不是Date。因此,我發送Date類型參數。 – 2012-03-31 05:37:46

1

以防萬一,如果有人還在尋找一個答案,希望這有助於 的解決方法是適當方言配置它,在我的情況下,它是NHibernate.Dialect.Oracle10gDialect

相關問題