百万级就得几分钟,这子查询怎优化?

会稽梁山伯 2020-01-02 01:40:30
select

(
select count(tli.overspeed)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.overspeed > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as overspeed,

(
select count(tli.hurriedlySpeedUp)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.hurriedlySpeedUp > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as hurriedlySpeedUp,

(
select count(tli.hurriedlySpeedDown)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.hurriedlySpeedDown > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as hurriedlySpeedDown,

(
select count(tli.fatigue)
from
TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.fatigue > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as fatigue,

(
select count(tli.leftLight)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.leftLight > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as leftLight,

(
select count(tli.rightLight)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.rightLight > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as rightLight,

(select count(tli.farLight)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.farLight > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as farLight,

(select count(tli.nearLight)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.nearLight > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as nearLight,

(select count(tli.brake)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.brake > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as brake,

(case when(
select sum(tli.timeInterval)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
)> 0 then (
select sum(tli.timeInterval)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) else 0 end) as totalTime,

(case when(
select sum(tli.timeInterval)
from TerminalLocationInfo tli
where HOUR(tli.actionTime) < 5
and tli.truckId = tk.id
and tli.driverId = d.id
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
)> 0 then (
select sum(tli.timeInterval)
from TerminalLocationInfo tli
where HOUR(tli.actionTime) < 5
and tli.truckId = tk.id
and tli.driverId = d.id
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) else 0 end) as totalNightTime,

(
select count(tli.night)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and HOUR(tli.actionTime) < 5
and tli.driverId = d.id
and tli.night > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as night,

(
select count(tli.acc)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and tli.acc > 0
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as acc,

(
select count(tli.id)
from TerminalLocationInfo tli
where tli.truckId = tk.id
and tli.driverId = d.id
and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
) as totalCount
from
Truck tk
left join TerminalLocationInfo TLI on TLI.truckId = tk.id
left join Company C on C.id = tk.companyId
left join Driver d on d.id = TLI.driverId
where
TLI.actionTime >= "2018-01-01 00:00:00"
and

TLI.actionTime <= "2018-01-01 23:59:59"
and

TLI.actionTime >= "2019-01-01"

group by tk.id,d.id
order by TLI.actionTime
...全文
77 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
会稽梁山伯 2020-01-03
  • 打赏
  • 举报
回复
引用 6 楼 吉普赛的歌 的回复:
报表的常见的几个优化方向: 1. 加索引; 2. 中间结果用临时表缓存; 3. 每天凌晨生成结果表,用户查询时只查结果表,以空间换时间。
对,这几个都是有试过,主要还是sql语句的优化,子查询还得尽量的少。而且,这个其实就是进行统计做结果表。
会稽梁山伯 2020-01-03
  • 打赏
  • 举报
回复
引用 5 楼 砸死牛顿的苹果 的回复:

TLI.actionTime <= "2018-01-01 23:59:59"
  and
TLI.actionTime >= "2019-01-01"
你确定有结果吗?
这个只是临时改了下数值。
会稽梁山伯 2020-01-03
  • 打赏
  • 举报
回复
引用 2 楼 文盲老顾 的回复:
select sum(case when tli.overspeed > 0 then 1 else 0 end) as overspeed
	,sum(case when tli.hurriedlySpeedUp > 0 then 1 else 0 end) as hurriedlySpeedUp
	,sum(case when tli.hurriedlySpeedDown > 0 then 1 else 0 end) as hurriedlySpeedDown
	,sum(case when tli.fatigue > 0 then 1 else 0 end) as fatigue
	,sum(case when tli.leftLight > 0 then 1 else 0 end) as leftLight
	,sum(case when tli.rightLight > 0 then 1 else 0 end) as rightLight
	,sum(case when tli.farLight > 0 then 1 else 0 end) as farLight
	,sum(case when tli.nearLight > 0 then 1 else 0 end) as nearLight
	,sum(case when tli.brake > 0 then 1 else 0 end) as brake
from
Truck tk
left join TerminalLocationInfo  tli
on tli.truckId = tk.id and tli.driverId = d.id and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
left join    Company C                   on    C.id = tk.companyId
left join    Driver d                    on    d.id = TLI.driverId
where TLI.actionTime >= "2018-01-01 00:00:00"
and TLI.actionTime <= "2018-01-01 23:59:59"
and TLI.actionTime >= "2019-01-01"
group by tk.id,d.id
order by TLI.actionTime
后边的case when 部分没仔细看,大概就这么个意思 由于你每个 count,都从新执行了一个子查询,那效率肯定很低了,你既然在外边已经有了left join,那么直接sum(case when 条件符合 then 1 else 0 end)肯定比你执行子查询快
对,2楼老顾这样是行的。重点还是子查询导致,之前其实有这样写过,但数据不正确,可能是写法不对。
吉普赛的歌 2020-01-02
  • 打赏
  • 举报
回复
报表的常见的几个优化方向: 1. 加索引; 2. 中间结果用临时表缓存; 3. 每天凌晨生成结果表,用户查询时只查结果表,以空间换时间。
  • 打赏
  • 举报
回复

TLI.actionTime <= "2018-01-01 23:59:59"
and
TLI.actionTime >= "2019-01-01"

你确定有结果吗?
文盲老顾 2020-01-02
  • 打赏
  • 举报
回复

-- 一个小例子
select companyId  -- 企业ID
,count(0) as total  -- 产品总数
,sum(case when isOnline=1 and isDelete=0 then 1 else 0 end) as online_products -- 已上线产品总数
,sum(case when isDelete=1 then 1 else 0 end) as deleted_products    -- 已删除产品总数
,sum(case when isOnline=0 and isDelete=0 then 1 else 0 end) as unchecked_products  -- 未审核产品总数
from products
group by companyId
文盲老顾 2020-01-02
  • 打赏
  • 举报
回复
现在的问题就是,子查询和外边的关联查询的条件是否一致,如果不一致,那么在最外层的条件里,再套个子查询,统计好了之后再用外层条件
文盲老顾 2020-01-02
  • 打赏
  • 举报
回复
select sum(case when tli.overspeed > 0 then 1 else 0 end) as overspeed
	,sum(case when tli.hurriedlySpeedUp > 0 then 1 else 0 end) as hurriedlySpeedUp
	,sum(case when tli.hurriedlySpeedDown > 0 then 1 else 0 end) as hurriedlySpeedDown
	,sum(case when tli.fatigue > 0 then 1 else 0 end) as fatigue
	,sum(case when tli.leftLight > 0 then 1 else 0 end) as leftLight
	,sum(case when tli.rightLight > 0 then 1 else 0 end) as rightLight
	,sum(case when tli.farLight > 0 then 1 else 0 end) as farLight
	,sum(case when tli.nearLight > 0 then 1 else 0 end) as nearLight
	,sum(case when tli.brake > 0 then 1 else 0 end) as brake
from
Truck tk
left join TerminalLocationInfo  tli
on tli.truckId = tk.id and tli.driverId = d.id and str_to_date(tli.actionTime,'%Y-%m-%d') = str_to_date(TLI.actionTime,'%Y-%m-%d')
left join    Company C                   on    C.id = tk.companyId
left join    Driver d                    on    d.id = TLI.driverId
where TLI.actionTime >= "2018-01-01 00:00:00"
and TLI.actionTime <= "2018-01-01 23:59:59"
and TLI.actionTime >= "2019-01-01"
group by tk.id,d.id
order by TLI.actionTime
后边的case when 部分没仔细看,大概就这么个意思 由于你每个 count,都从新执行了一个子查询,那效率肯定很低了,你既然在外边已经有了left join,那么直接sum(case when 条件符合 then 1 else 0 end)肯定比你执行子查询快
sxq129601 2020-01-02
  • 打赏
  • 举报
回复
搞个报表库吧

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧