JPA解决时间类型不一致导致索引不生效问题(一)

发布网友 发布时间:2024-09-29 02:48

我来回答

1个回答

热心网友 时间:2024-11-06 22:36

一.场景

在某一功能点击根据时间查询,查询速度达到2分钟,而且为单表查询,表数据量600w

二.验证问题

将sql在数据库可视化工具中执行,发现执行速度正常,而且走索引。但是,在应用中查询,却达到2分钟。

三.分析

在应用中查询应该没有走索引,因为字段为时间字段,那么很可能是在数据库做了函数转换。

四.解决

操作1在测试环境还原,测试环境该表数据量50w,体现不出加所以和不加索引的区别

操作2联系DBADBA说存在,时间类型在数据库中增加了函数转换

操作3在测试环境数据库增加表并设定为600w条数据

createtabletest_tableasselectrownumasidfromxmltable('1to6000000');altertabletest_tableadd(printed_DateDATE);ALTERTABLEtest_tableADD(IDENTITY_CARDVARCHAR2(20CHAR));ALTERTABLEtest_tableADD(COMMITMENT_NC_CODEVARCHAR2(128CHAR));COMMENTONCOLUMNtest_table.COMMITMENT_NC_CODEIS'应收结算单位NC代码';ALTERTABLEtest_tableADD(CUSTOMS_NC_CODEVARCHAR2(128CHAR));COMMENTONCOLUMNtest_table.CUSTOMS_NC_CODEIS'供应商NC代码';ALTERTABLEtest_tableADD(COMMITMENT_NC_CODEVARCHAR2(128CHAR));COMMENTONCOLUMNtest_table.COMMITMENT_NC_CODEIS'应收结算单位NC代码';ALTERTABLEtest_tableADD(CUSTOMS_NC_CODEVARCHAR2(128CHAR));COMMENTONCOLUMNtest_table.CUSTOMS_NC_CODEIS'供应商NC代码';ALTERTABLEtest_tableADD(FREIGHT_TYPEVARCHAR2(128CHAR));COMMENTONCOLUMNtest_table.FREIGHT_TYPEIS'费用类别';

为表添加数据

这里可以设置不同时间UPDATEtest_tableSETPRINTED_DATE=sysdate+10WHEREID>1000000andID<3000000为同一列不同行设置随机数updatetest_tablersetr.FREIGHT_TYPE=(selectfloor(dbms_random.value(100,99999999))fromal)whereid>2000000andid<2100000对printed_Date添加索引CREATEINDEXIDX_test_table2ONtest_table(printed_date);

在java中增加实体类

/***@author子羽*@Description测试实体类*@Date2021/8/30*/@Entity@Table(name="TEST_TABLE")publicclassTestTable{@Id@GeneratedValue(strategy=GenerationType.AUTO)privateStringid;privateDateprintedDate;privateStringcommitmentNcCode;privateStringfreightType;-------}

执行查询

SELECT*FROM(SELECT*FROMtest_tabletesttable0_WHERE1=1ANDtesttable0_.printed_date>=TO_DATE('2017-08-31','yyyy-mm-dd')ANDtesttable0_.printed_date<TO_DATE('2021-09-30','yyyy-mm-dd')ORDERBYtesttable0_.printed_dateDESC)WHERErownum<=11;

在数据库可视化工具中查询查询时间不到2s在测试环境页面执行查询查询时间接近6s

说明页面查询没有走索引

分析:jpa底层是orm框架,是不是时间属性的映射有问题,于是在时间属性printed_date上增加@Temporal(TemporalType.DATE)注解

@Entity@Table(name="TEST_TABLE")publicclassTestTable{@Id@GeneratedValue(strategy=GenerationType.AUTO)privateStringid;@Temporal(TemporalType.DATE)privateDateprintedDate;privateStringcommitmentNcCode;privateStringfreightType;-----}

在页面执行查询,查询时间不到2s,和数据库可视化工具查询时间一一致

进一步测试,删除索引

dropindexIDX_test_table2;

页面查询时间接近6s,完全证明页面查询走了索引。

结论

就算java中的属性是Date类型,也要在属性上标记@Temporal(TemporalType.DATE),否则无法和数据库中的字段最映射,查询时会出现数据库*的函数转换,导致索引失效。

作者:千云著作权归作者所有。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com