Hibernate联合子类(每个具体类的表)“增量”映射生成器很慢?

发布于 2024-12-07 07:03:32 字数 2894 浏览 0 评论 0 原文

我的 Hibernate hbm 文件与 mysql 数据库类似:

<hibernate-mapping>
<class name="com.company.common.bo.position.Parent" table="Parents"
    abstract="true">
    <id name="id">
        <generator class="increment" />
    </id>
    <property name="date" not-null="true" />
    <property name="milliseconds" not-null="true" />
    <property name="shares">
        <column name="shares" precision="19" scale="6" not-null="true" />
    </property>
    <many-to-one name="ticker" column="tickerID" not-null="true" index="_tickerID_date_milliseconds_idx" />
    <many-to-one name="auditTrail" column="auditTrailID"
        not-null="false" cascade="save-update" lazy="false" fetch="select" />

    <union-subclass name="com.company.common.bo.position.SubclassA"
        table="SubclassAs">
        <many-to-one name="account" column="accountID" not-null="true" foreign-key="SubclassA_accountID_fk" />
        <many-to-one name="portfolio">
            <column name="portfolioID" not-null="true"/>
        </many-to-one>
        <many-to-one name="individualTrade">
            <column name="individualTradeID" not-null="false"/>
        </many-to-one>  
        <many-to-one name="positionTransfer" column="positionTransferID"
                cascade="save-update" not-null="false"/>
    </union-subclass>

    <union-subclass
            name="com.company.common.bo.position.SubclassB" table="SubclassBs">
        <many-to-one name="individualTrade">
            <column name="individualTradeID" not-null="false" />
        </many-to-one>  
        <many-to-one name="account" column="accountID" not-null="true" foreign-key="SubclassBs_accountID_fk"/>
        <many-to-one name="internalExecution" column="executionID"
                cascade="save-update" not-null="false" />
    </union-subclass>       

    <union-subclass name="com.company.common.bo.position.SubclassC"
        table="SubclassCs">
    </union-subclass>
</class>

所以基本上我有一个抽象类 Parent 和扩展它的 3 个子类(SubclassA、B、C)。数据库中有 3 个表(针对 3 个子类)。 id 生成器是“增量”的,因为联合子类映射不允许我使用本机。所以看起来随着增量,ID 在 3 个表中是唯一的。当我查看 hibernate sql 时,它基本上从所有 3 个表中找到最大 ID,并将其用作下一个 ID。但它使用的查询似乎效率很低。这就是我所看到的:

select max(ids_.id) from ( select id from SubclassAs union select id from SubclassBs union select id from SubclassCs ) ids_ 

运行时间超过 12 秒。每个表都有超过一百万条记录。它将每个 ID 合并在一起,然后从中选择最大值。

如果我这样做:

select max(ids_.id) from ( select max(id) as id from SubclassAs union select max(id) as id from SubclassBs union select max(id) as id from SubclassCs ) ids_

它要快得多,不到一毫秒,因为内部联合只从每个表中获取最大值,然后我只选择这 3 条记录中的最大值。

有没有办法告诉 hibernate 这样做,或者有没有更好的方法在这 3 个表中使用 ID 生成器?

谢谢

My Hibernate hbm file looks something like this with a mysql DB:

<hibernate-mapping>
<class name="com.company.common.bo.position.Parent" table="Parents"
    abstract="true">
    <id name="id">
        <generator class="increment" />
    </id>
    <property name="date" not-null="true" />
    <property name="milliseconds" not-null="true" />
    <property name="shares">
        <column name="shares" precision="19" scale="6" not-null="true" />
    </property>
    <many-to-one name="ticker" column="tickerID" not-null="true" index="_tickerID_date_milliseconds_idx" />
    <many-to-one name="auditTrail" column="auditTrailID"
        not-null="false" cascade="save-update" lazy="false" fetch="select" />

    <union-subclass name="com.company.common.bo.position.SubclassA"
        table="SubclassAs">
        <many-to-one name="account" column="accountID" not-null="true" foreign-key="SubclassA_accountID_fk" />
        <many-to-one name="portfolio">
            <column name="portfolioID" not-null="true"/>
        </many-to-one>
        <many-to-one name="individualTrade">
            <column name="individualTradeID" not-null="false"/>
        </many-to-one>  
        <many-to-one name="positionTransfer" column="positionTransferID"
                cascade="save-update" not-null="false"/>
    </union-subclass>

    <union-subclass
            name="com.company.common.bo.position.SubclassB" table="SubclassBs">
        <many-to-one name="individualTrade">
            <column name="individualTradeID" not-null="false" />
        </many-to-one>  
        <many-to-one name="account" column="accountID" not-null="true" foreign-key="SubclassBs_accountID_fk"/>
        <many-to-one name="internalExecution" column="executionID"
                cascade="save-update" not-null="false" />
    </union-subclass>       

    <union-subclass name="com.company.common.bo.position.SubclassC"
        table="SubclassCs">
    </union-subclass>
</class>

So basically i have an abstract class Parent and 3 subclasses (SubclassA, B, C) that extend it. In the database there are 3 tables (for the 3 subclasses). The id generator is "increment" because the union subclass mapping doesn't allow me to use native. So it looks like with increment, the ID is unique among the 3 tables. When I look at the hibernate sql, it basically finds the max ID from all 3 tables, and uses that as the next ID. But the query it uses seems very inefficient. This is what I see it doing:

select max(ids_.id) from ( select id from SubclassAs union select id from SubclassBs union select id from SubclassCs ) ids_ 

Which takes over 12 seconds to run. Each of those tables has more than a million records each. It's unioning every single ID together and then selecting the max out of that.

If i do something like this:

select max(ids_.id) from ( select max(id) as id from SubclassAs union select max(id) as id from SubclassBs union select max(id) as id from SubclassCs ) ids_

It is much faster, less than one millisecond, because the inner union only gets the max from each table, and then i select just the max out of those 3 records.

Is there a way to tell hibernate to do this instead, or is there a better way of using a generator for the ID across these 3 tables?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

记忆里有你的影子 2024-12-14 07:03:32

如果 increment 不能满足您的要求,您可以使用其他一些生成器策略,并且,由于 MySQL 不支持序列,因此下一个合适的选项是 hilo 策略

If increment doesn't satisfy you, you can use some other generator strategy, and, since MySQL doesn't support sequences, the next suitable option is a hilo strategy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文