oracle sql =号左边含有 TRIM 严重影响性能!

在使用Hibernate框架连接Oracle数据库时遇到CHAR类型字段导致PreparedStatement查询失效的问题。通过使用TRIM解决查询问题,却发现大量数据查询变得非常缓慢。去掉TRIM后,查询速度显著提升。

这学期的项目中,用hibernate和oracle。表结构我们不能改,这样的遗留系统用hibernate有点麻烦。汗!别人把可变长的字符类型设计为CHAR,郁闷死。这样所有?形式的sql语句基本上无效(不是恰好这么长就找不到数据),这是oracle的JDBC限定了(mysql的JDBC不会)。然后就想到在=号左边用TRIM可以解决PrepareStatement找不到数据的问题。

     麻烦来了。同学用100W行数据来测试。发现比较卡。然后追踪hibernate的SQL日志发现有trim的语句就慢。然后把此SQL语句在PL/SQL客户端试下,发现在26秒才能找到结果。汗!这么严重!去了TRIM不到1秒的事情。

     字段类型的设计不好,就这样...

     用TRIM的初衷是为了解决 oracle jdbc char 字段 PreparedStatement 查询问题 .

<!-- 主查询:只查询主表信息 --> <select id="queryPurchaseOrderPage" resultType="com.hvlink.entity.dto.order.PurchaseOrderMainDTO"> SELECT m.id, m.company_code, m.purchase_order_no, m.publish_date, s.supplier_code, s.supplier_name, f.factory_code, f.factory_name, w.warehouse_code, w.warehouse_name, m.serial_version_num, m.order_type FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY purchase_order_no, company_code ORDER BY serial_version_num DESC) as rn FROM tb_order_main WHERE is_deleted = 0 ) m LEFT JOIN tm_supplier s ON m.supplier_code = s.supplier_code AND m.company_code = s.company_code LEFT JOIN tm_factory f ON m.factory_code = f.factory_code AND m.company_code = f.company_code LEFT JOIN tm_warehouse w ON m.warehouse_code = w.warehouse_code AND m.company_code = w.company_code <where> m.rn = 1 <!-- 只取每个订单的最新版本 --> <!-- 优化后的模糊匹配组 --> <if test="param.supplierName != null and param.supplierName != '' or param.supplierCode != null and param.supplierCode != '' or param.factoryName != null and param.factoryName != '' or param.factoryCode != null and param.factoryCode != '' or param.warehouseName != null and param.warehouseName != '' or param.warehouseCode != null and param.warehouseCode != ''"> AND ( <trim prefixOverrides="OR"> <!-- 供应商条件 --> <if test="param.supplierName != null and param.supplierName != ''"> OR s.supplier_name LIKE '%' + #{param.supplierName} + '%' </if> <if test="param.supplierCode != null and param.supplierCode != ''"> OR s.supplier_code LIKE '%' + #{param.supplierCode} + '%' </if> <!-- 工厂条件 --> <if test="param.factoryName != null and param.factoryName != ''"> OR f.factory_name LIKE '%' + #{param.factoryName} + '%' </if> <if test="param.factoryCode != null and param.factoryCode != ''"> OR f.factory_code LIKE '%' + #{param.factoryCode} + '%' </if> <!-- 仓库条件 --> <if test="param.warehouseName != null and param.warehouseName != ''"> OR w.warehouse_name LIKE '%' + #{param.warehouseName} + '%' </if> <if test="param.warehouseCode != null and param.warehouseCode != ''"> OR w.warehouse_code LIKE '%' + #{param.warehouseCode} + '%' </if> </trim> ) </if> <!-- 订单模糊查询 --> <if test="param.purchaseOrderNo != null and param.purchaseOrderNo != ''"> AND m.purchase_order_no LIKE '%' + #{param.purchaseOrderNo} + '%' </if> <if test="param.startDate != null"> AND m.publish_date >= #{param.startDate} </if> <if test="param.endDate != null"> AND m.publish_date <= #{param.endDate} </if> <!-- 订单类型 --> <if test="param.orderType != null"> AND m.order_type = #{param.orderType} </if> <!-- 明细字段关联查询 - 使用EXISTS优化性能 --> <if test="param.partCode != null and param.partCode != ''"> AND EXISTS ( SELECT 1 FROM tb_order_detail d WHERE d.purchase_order_no = m.purchase_order_no AND d.company_code = m.company_code AND d.serial_version_num = m.serial_version_num AND d.part_code LIKE '%' + #{param.partCode} + '%' ) </if> <if test="param.partDesc != null and param.partDesc != ''"> AND EXISTS ( SELECT 1 FROM tb_order_detail d WHERE d.purchase_order_no = m.purchase_order_no AND d.company_code = m.company_code AND d.serial_version_num = m.serial_version_num AND d.part_desc LIKE '%' + #{param.partDesc} + '%' ) </if> <if test="param.frequency != null and param.frequency != ''"> AND EXISTS ( SELECT 1 FROM tb_order_detail d WHERE d.purchase_order_no = m.purchase_order_no AND d.company_code = m.company_code AND d.serial_version_num = m.serial_version_num AND d.frequency = #{param.frequency} ) </if> </where> ORDER BY s.supplier_code DESC, m.purchase_order_no DESC </select> <select id="selectLatestByOrderIds" resultType="com.hvlink.entity.dto.order.PurchaseOrderMainDTO"> SELECT m.id, m.company_code, m.purchase_order_no, m.publish_date, s.supplier_code, s.supplier_name, f.factory_code, f.factory_name, w.warehouse_code, w.warehouse_name, m.serial_version_num, m.order_type FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY purchase_order_no, company_code ORDER BY serial_version_num DESC) as rn FROM tb_order_main WHERE is_deleted = 0 AND id IN <foreach collection="orderIds" item="id" open="(" close=")" separator=","> #{id} </foreach> ) m LEFT JOIN tm_supplier s ON m.supplier_code = s.supplier_code AND m.company_code = s.company_code LEFT JOIN tm_factory f ON m.factory_code = f.factory_code AND m.company_code = f.company_code LEFT JOIN tm_warehouse w ON m.warehouse_code = w.warehouse_code AND m.company_code = w.company_code WHERE m.rn = 1 ORDER BY m.create_time DESC </select> 进行性能优化,并帮我检查是否有错误
最新发布
09-25
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值