一些同事提出了一个问题,他们发现查询执行时间很慢,并且发现由于隐式类型转换而未使用索引。
kgb_uuid
该表有一个用于存储 UUID 的属性。该列被定义为VARCHAR2
并具有一个索引,用于通过 UUID 搜索行。
实体中的相关字段定义为String
。根据 Hibernate 文档,Hibernate 应该将此字符串转换为VARCHAR2
Oracle 数据库,因此应该使用索引。
但事实并非如此,如日志所示:
[9/2/19 11:56:07:610 CEST] 00000177 SystemOut O
2019-09-02T11:56:07,610 TRACE [ebContainer : 3] ibebcTraceInterceptor;log;;41 - 类 [MyDAO] 中的入口方法 [checkEindeutigeUUID]带参数 (MyEntity@b14745f9)[9/2/19 11:56:07:688 CEST] 00000177 SQL Z org.hibernate.engine.jdbc.spi.SqlStatementLogger logStatement 选择 count(mytab0_.KGB_NR) as col_0_0_ from MYENTITYTABLE mytab_ where mytab_.KGB_UUID=?和 mytab_.EKN_NR=?
[9/2/19 11:56:07:688 CEST] 00000177 BasicBinder Z org.hibernate.type.descriptor.sql.BasicBinder 绑定参数 [1] 作为 [VARCHAR] - 795BF3B98D879358E0531C03A90ABF0A [9/2/19 11:56 :07:688 CEST] 00000177 BasicBinder Z org.hibernate.type.descriptor.sql.BasicBinder 绑定绑定参数 [2] 作为 [BIGINT] - 1
正如所见,字符串值被绑定为VARCHAR
not as VARCHAR2
,导致数据库进行隐式类型转换并且不使用索引,如 OEM 中所示(这是来自 OEM 的原始德语消息):
执行计划的行 ID 3 中使用的谓词 SYS_OP_C2C("mytab_"."KGB_UUID")=:B1 包含索引列“KGB_UUID”上的隐式数据类型转换。这种隐式数据类型转换会阻止优化器有效地使用表“MYENTITYTABLE”上的索引。
它表示使用了谓词SYS_OP_C2C("mytab_"."KGB_UUID")=:B1
,并且它包含索引基列的隐式属性类型的对话KGB_UUID
,并且该隐式类型的对话阻止优化器有效地使用表的索引MYENTITYTABLE
。
我们已经解决了在表上使用功能索引的问题,但我们仍然想知道为什么 Hibernate 提供了一种显然不是VARCHAR2
.
系统:
Hibernate 4.2.21 与 Hibernate Dialect Oracle10g(根据文档最多兼容 12 个)
Oracle 12.2(现在不完全是,我认为是12.2,但也许只是12.1)
Hibernate 版本无法升级,因为它是可与 JPA 2.0 一起使用的最后一个版本,JPA 2.0 是 Websphere Process Server 8.5 支持的 JavaEE 6 的一部分。
(简称)实体
@Entity
@Table(name = "MYENTITYTABLE")
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
// out commented the sequence generator
@Column(name="KGB_NR")
private long kgbNr;
@Column(name="KGB_UUID")
private String kgbUuid; // <<== DEFINED AS STRING!
//bi-directional many-to-one association to Ekistnutzer
@ManyToOne
@JoinColumn(name="EKN_NR")
private EkistnutzerEntity ekistnutzer;
// Other attributes not related in problem
}
青春有我
相关分类