2011-11-23 44 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

相关问题