opMainPlanDetail是一个数据量较大的表, opMainPlanDetail表包含了StationCode和PassTime(日期字符串)两个索引。下列采用了两种方式查询速度比较:
方式1,花费了近60s,多执行几遍,有时候6s左右:
select COUNT(distinct det.ID)个数, us.UserName
from opMainPlanDetail det with(nolock)
inner join syUser us with(nolock) on us.LoginID=det.OperatorAccount
where StationCode in ('2150','2170','2155','3600','3700','2215','3650','3660' ,'2158','5013','5042')
and PassTime >= '2024-11-01' and PassTime < '2024-12-01'
group by us.UserName
查看执行计划
方式2:日期经过转换,执行只花了3s左右:
select COUNT(distinct det.ID)个数, us.UserName
from opMainPlanDetail det with(nolock)
inner join syUser us with(nolock) on us.LoginID=det.OperatorAccount
where StationCode in ('2150','2170','2155','3600','3700','2215','3650','3660' ,'2158','5013','5042')
and convert(char(10), cast(PassTime as date)) >= '2024-11-01' and convert(char(10), cast(PassTime as date)) < '2024-12-01'
group by us.UserName
查看执行计划
运行了多次,方式1总是比方式2花费的时间长。按照我的理解,方式1直接用了PassTime索引,按说执行的应该更快一点,实际结果却是相反的。
看执行计划像是方式2采用了并行查询,不太理解这个地方,盼哪位大佬为小弟解下惑,谢谢!
1.索引利用: 在方式1中,直接使用字符串比较没有充分利用索引。而在方式2中,通过将PassTime转换为日期格式,查询优化器可能更容易利用索引,从而加快查询速度。
2.数据类型转换: 方式2中,convert和cast函数将字符串转换为日期格式,这样的转换可能减少了查询过程中不必要的字符串比较操作,提高了效率。