2011-11-23 61 views
6

在Oracle中我有一個分區表。分區大小不同,數據分佈不同。有什麼辦法讓Hibernate使用文字值而不是綁定變量嗎?

我想休眠問題的SQL語句,包括分區鍵列而不是綁定變量的文字值。它當然應該使用綁定變量作爲任何其他值。

對分區鍵使用文字將允許Oracle提出特定於已知分區和收集統計信息的計劃。這對於偏斜數據具有直方圖的列可能也很有用。

最好在實體中指定它,否則我們需要在每個查詢中執行此操作。有沒有辦法做到這一點在休眠?

我們在使用Oracle 10g Dialect的hibernate 3.6.1。

如果在Hibernate中本地沒有辦法做到這一點,我可以創建一個用戶類型或方言或使其發生?

+1

會11g自適應光標共享解決您的問題? –

+0

@jonearles也許11g會通過自適應光標共享和/或基數反饋來解決這些問題。我們正在努力讓11g達到生產,但是在那裏要做相當多的測試。 –

+0

需要說明的是,您是否說分區修剪本身適用於綁定變量,但分區中的查詢計劃(例如,連接策略)不? – wrschneider

回答

1

不,Hibernate不支持字面值。我懷疑你是否可以制定解決方法,但我想你正在尋找另一種解決方案。

+2

如果在Hibernate中絕對沒有辦法做到,我們不會使用hibernate。 –

0

作爲一種解決方法,您可以在每個「有趣的」調用站點設置唯一的註釋,以便您可以控制Oracle的綁定變量窺視。

... 
query = session.createQuery("..."); 
... 
query.setString("param1", "FOO"); 
query.setInteger("param2", param2Value); 
... 
query.setComment("param1 = \"FOO\""); 
... 

通過這種方式,優化器將看到硬解析時間"FOO"(像往常一樣)。在將來的調用中,Oracle將搜索SQL的精確副本以重用執行計劃。由於註釋使查詢有效唯一,因此這將爲您提供與"FOO"計算的執行計劃相同的計劃,而不是任何其他值param1

您必須小心,因爲優化程序也將使用值param2Value來計算執行計劃,因此它可能會產生干擾。但我認爲至少這是值得一試的。

+1

由於引入了計劃不穩定性,我們禁用了綁定變量窺視。其中一個例子是夜間批量作業 - 無論哪個客戶的實例首先運行,爲後面的那些人設定了計劃。這並不總是好的。 –

+0

那麼這就是這個解決方法的要點:應該使用不同計劃的查詢獲得文本上不同的SQL,因此您不必禁用查看並失去其優勢。但是,你不打算爲此重新啓用它。 – gpeche

+0

你有沒有想過使用SQL配置文件的查詢,將受益於文字? – gpeche

1

您可以使用namedNativeQuery 這裏是一個示例實現。

實體類

@Entity 
@Table(catalog = DBCatalog) 
@org.hibernate.annotations.NamedNativeQuery(name="partitionTR1",query ="SELECT * FROM DATAMARTTRANSACTIONHISTORY PARTITION (tr1) where id=?",resultClass=DataMartTable.class) 
public class DataMartTransactionHistory implements TransactionHistory { 
    @Id 
    @Column 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    @Enumerated(EnumType.ORDINAL) 
    private TransactionStatus transactionStatus; 
... other props... 
} 

,這裏是一個DAO實現。

public DataMartTransactionHistory findDataMartTransactionHistoryTR1(Long id) { 
    Query namedQuery = getSessionFactory().getCurrentSession().getNamedQuery("partitionTR1"); 
    namedQuery.setLong(0, id); 
    return (DataMartTransactionHistory)namedQuery.list().get(0); 
} 
+0

。 CREATE TABLE DATAMARTTRANSACTIONHISTORY ( ID號碼(19)NOT NULL, .... 的TransactionStatus NUMBER(10) ) PARTITION BY LIST(的TransactionStatus)(分區TR1的值(1),分區TR2值(2)) – dursun

+0

在你的命名查詢中你有「where id =?」。你是說這將被替換爲文字值而不是綁定變量? –

+0

不,它是一個綁定變量,我已經將「PARTITION(tr1)」添加爲文字。你可以在這裏添加更多。如果你給我一個,你的具體用例,我可以給你一個具體的例子。 – dursun

相關問題