mybatis+sqlserver SQL语句如下:
select count(*) from tab_order order
<if test="orderType != null and orderType != ''"> and order.type = #{orderType } </if>
<if test="beginTime != null and beginTime != ''"> and order.CREATE_TIME <![CDATA[>= ]]> #{beginTime} </if>
<if test="endTime != null and endTime != ''"> and order.CREATE_TIME <![CDATA[<= ]]> #{endTime} </if>
省略部分查询条件,其中CREATE_TIME字段类型为datetime2,已经加上聚合索引,type 为 非聚合索引nvarchar,tab_order表中500W数据,此时页面选择时间段查询,后台打印日志为:
Preparing: select count(*) from tab_order order WHERE order.orderType = ? and order.CREATE_TIME >= ? and order.CREATE_TIME <= ?
Parameters: 2367 (String),2021-04-01 00:00:00.0(Timestamp), 2021-06-18 23:59:59.999(Timestamp)
查出来的结果是300W左右,耗时30S左右,
于是我怀疑是 因为CREATE_TIME类型是datetime2的,而传入参数是Timestamp的,是不是sqlserver做了啥隐式转换导致不走索引,于是改成
<if test="beginTimeStr != null and beginTimeStr != ''"> and order.CREATE_TIME <![CDATA[>= ]]> convert(datetime2,#{beginTimeStr}) </if>
<if test="endTimeStr != null and endTimeStr != ''"> and order.CREATE_TIME <![CDATA[<= ]]> convert(datetime2,#{endTimeStr}) </if>
把时间段做成字符串然后转成datetime2,可是结果还是一样,还是要30S。
但是如果把sql中的#{beginTime}和#{endTime}改成 $(beginTime)和$(endTime)查询的话,或者固定写成
order.CREATE_TIME >= convert(datetime2,'2021-04-01 00:00:00.0') and order.CREATE_TIME <= convert(datetime2,'2021-06-17 23:59:59.999') ,都很快基本2S左右结果出来,
还有直接在management studio中执行
select count(*) from tab_order order WHERE order.orderType = '2367 ' and order.CREATE_TIME >= convert(datetime2,'2021-04-01 00:00:00.0') and order.CREATE_TIME <= convert(datetime2,'2021-06-17 23:59:59.999')
也是秒级就出来,看执行过程也没任何问题
是否有遇到过这个问题朋友,求解了?