有什么方法可以改写select语句,以便查询运行得更快

时间:2019-08-29 13:17:22

标签: sql sql-server tsql

我使用一个相当高级的查询,该查询基于已计算数据本身的视图,其中包含许多已计算数据。创建此查询需要花费大量时间,这是一个问题,因为该查询用于填充Microsoft powerBI的数据模型。每次刷新仪表盘时,我选择的查询都会刷新,尤其是这个查询需要花费很多时间才能刷新。

是否有任何方法可以重写select语句,以使刷新不会花费4-6个工作日?

select top 10 x.model, count(x.model) as 'aantal gedraaid', 
(select avg(deltasec) from dbo.Testview1 where categorie = 'geen stop' and model = x.model) as 'gemiddelde tijd', 
(select count(model) from dbo.Testview1 where categorie in ('Lange stop', 'korte stop') and model = x.model ) as 'aantal stops',
((select sum(deltasec) from dbo.Testview1 where categorie not in ('setuptijd', 'uitschieter') and model = x.model )/3600) as 'total runtime',
((select sum(deltasec) from dbo.Testview1 where categorie in ('geen stop') and model = x.model )/3600) + (select ((cast((select count(model) from dbo.Testview1 where categorie in ('Lange stop', 'korte stop') and model = x.model) as real))* (select avg(deltasec) from dbo.Testview1 where categorie = 'geen stop' and model = x.model ))/3600)   'tijd geen stop',
((select sum(deltasec) from dbo.Testview1 where categorie in ('Lange stop', 'korte stop') and model = x.model )/3600) - (select ((cast((select count(model) from dbo.Testview1 where categorie in ('Lange stop', 'korte stop') and model = x.model) as real))* (select avg(deltasec) from dbo.Testview1 where categorie = 'geen stop' and model = x.model ))/3600) 'tijd stop',
((select sum(deltasec) from dbo.Testview1 where categorie in ('setuptijd') and model = x.model )/3600) as 'setuptijd',
(select min(deltasec) from dbo.testview1 where categorie = 'geen stop' and model = x.model) as 'beste tijd'
from dbo.Testview1 x 
where actie_id = 48 and model <> 'UFO'
group by model
order by max(x.datum) desc

编辑testview1视图设计的快速草稿

48  nieuw PCB   2019-08-29  14:40:08.7700000    UFO 201908291440    00:00:05.8600000    5,86    uitschieter
48  nieuw PCB   2019-08-29  14:40:02.9100000    UFO 201908291440    00:00:32.4730000    32,47333    geen stop
48  nieuw PCB   2019-08-29  14:39:30.4370000    UFO 201908291439    00:01:31.0300000    91,03001    korte stop
48  nieuw PCB   2019-08-29  14:37:59.4070000    UFO 201908291438    02:00:01.0770000    7201,077    Lange stop
48  nieuw PCB   2019-08-29  12:37:58.3300000    UFO 201908291238    00:00:14.2070000    14,20667    geen stop
48  nieuw PCB   2019-08-29  12:37:44.1230000    UFO 201908291237    00:13:27.4100000    807,41  Lange stop
48  nieuw PCB   2019-08-29  12:24:16.7130000    UFO 201908291224    00:00:26.1670000    26,16667    geen stop
48  nieuw PCB   2019-08-29  12:23:50.5470000    UFO 201908291224    00:00:25.1270000    25,12667    geen stop
48  nieuw PCB   2019-08-29  12:23:25.4200000    UFO 201908291223    00:00:26.4100000    26,41   geen stop
48  nieuw PCB   2019-08-29  12:22:59.0100000    UFO 201908291223    00:00:25.5400000    25,54   geen stop
48  nieuw PCB   2019-08-29  12:22:33.4700000    UFO 201908291222    00:00:25.0600000    25,06   geen stop
48  nieuw PCB   2019-08-29  12:22:08.4100000    UFO 201908291222    00:00:24.7230000    24,72334    geen stop
48  nieuw PCB   2019-08-29  12:21:43.6870000    UFO 201908291221    00:01:24.6670000    84,66667    korte stop

查询以选择此视图

select x.*, 
case
    when datum <> lead(datum) over (order by datum desc, tijd desc) then 'uitschieter'
    when lead(actie_id) over (order by datum desc, tijd desc) = 36 and (lead(custom1) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,2) over (order by datum desc, tijd desc) = 36 and (lead(custom1,2) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,2) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,3) over (order by datum desc, tijd desc) = 36 and (lead(custom1,3) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,3) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,4) over (order by datum desc, tijd desc) = 36 and (lead(custom1,4) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,4) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,5) over (order by datum desc, tijd desc) = 36 and (lead(custom1,5) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,5) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when actie_id = 36 then 'uitschieter'
    When deltasec > 200 then 'Lange stop'
    When deltasec <200 and deltasec >60 then 'korte stop'
    When deltasec < 60 and deltasec > 10 then 'geen stop'
    else 'uitschieter'
    end as [Categorie]
from 
(select T_event.Actie_ID, 
case 
    when actie_omschrijving = 'foto' then 'nieuw PCB'
    when actie_omschrijving = 'is leeg' then 'start/stop model'
end as omschrijving,
cast(event_timestamp as date) as datum, cast(event_timestamp as time) as tijd, 
case 
    when left(custom1,4) like '201_%' then 'UFO'
    when t_event.Actie_ID = 48 then left(custom1,4)
    when t_event.Actie_ID = 36 then 'start/stop'
end as model,
custom1, 
cast(T_event.event_timestamp - Lag(T_event.event_timestamp) over (order by T_event.Event_ID) AS time) [Delta],
cast(T_event.event_timestamp - Lag(T_event.event_timestamp) over (order by T_event.Event_ID) AS real) * 86400 as deltasec
from T_event
  inner join T_Actie ON T_event.Actie_ID = T_Actie.Actie_ID
WHERE T_EVENT.Actie_ID in (36,34,48) and t_event.custom1 not like 'einde%'
  and Event_Timestamp >= '2019-07-22') x

原始T_Event数据集

其他信息:  这是代表制造工厂的数据。每当产品进入制造的最后阶段时,就会记录带有相应时间戳的事件。我的老板要我分析这些数据并将其可视化显示在仪表板上

83  28  2   2012-05-08 08:31:06.843 038200000168    NULL    NULL    NULL    NULL
84  28  2   2012-05-08 08:31:08.063 038200000170    NULL    NULL    NULL    NULL
85  28  2   2012-05-08 08:51:27.437 038200000164    NULL    NULL    NULL    NULL
86  28  2   2012-05-08 08:51:29.250 038200000166    NULL    NULL    NULL    NULL
87  28  2   2012-05-08 08:52:58.530 038200000160    NULL    NULL    NULL    NULL
88  28  2   2012-05-08 08:52:59.953 038200000162    NULL    NULL    NULL    NULL
89  28  2   2012-05-08 08:53:42.483 038200000152    NULL    NULL    NULL    NULL
90  28  2   2012-05-08 08:53:43.703 038200000154    NULL    NULL    NULL    NULL
91  28  2   2012-05-08 08:54:24.280 038200000156    NULL    NULL    NULL    NULL
92  28  2   2012-05-08 08:54:25.750 038200000158    NULL    NULL    NULL    NULL
93  28  2   2012-05-08 09:02:54.720 038200000148    NULL    NULL    NULL    NULL

1 个答案:

答案 0 :(得分:0)

所以我的建议如下:

if exists(select 1 from sysobjects where name = 'fn_SelectQuery_AL')
drop function fn_SelectQuery_AL;

set ansi_nulls on
go

set quoted_identifier on
go

create function fn_SelectQuery_AL()
returns table
with encryption
as
return
(
select x.*, 
case
    when datum <> lead(datum) over (order by datum desc, tijd desc) then 'uitschieter'
    when lead(actie_id) over (order by datum desc, tijd desc) = 36 and (lead(custom1) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,2) over (order by datum desc, tijd desc) = 36 and (lead(custom1,2) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,2) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,3) over (order by datum desc, tijd desc) = 36 and (lead(custom1,3) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,3) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,4) over (order by datum desc, tijd desc) = 36 and (lead(custom1,4) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,4) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when lead(actie_id,5) over (order by datum desc, tijd desc) = 36 and (lead(custom1,5) over (order by datum desc, tijd desc) like 'Start%' or lead(custom1,5) over (order by datum desc, tijd desc) like 'begin%') then 'setuptijd'
    when actie_id = 36 then 'uitschieter'
    When deltasec > 200 then 'Lange stop'
    When deltasec <200 and deltasec >60 then 'korte stop'
    When deltasec < 60 and deltasec > 10 then 'geen stop'
    else 'uitschieter'
    end as [Categorie]
from 
(select T_event.Actie_ID, 
case 
    when actie_omschrijving = 'foto' then 'nieuw PCB'
    when actie_omschrijving = 'is leeg' then 'start/stop model'
end as omschrijving,
cast(event_timestamp as date) as datum, cast(event_timestamp as time) as tijd, 
case 
    when left(custom1,4) like '201_%' then 'UFO'
    when t_event.Actie_ID = 48 then left(custom1,4)
    when t_event.Actie_ID = 36 then 'start/stop'
end as model,
custom1, 
cast(T_event.event_timestamp - Lag(T_event.event_timestamp) over (order by T_event.Event_ID) AS time) [Delta],
cast(T_event.event_timestamp - Lag(T_event.event_timestamp) over (order by T_event.Event_ID) AS real) * 86400 as deltasec
from T_event
  inner join T_Actie ON T_event.Actie_ID = T_Actie.Actie_ID
WHERE T_EVENT.Actie_ID in (36,34,48) and t_event.custom1 not like 'einde%'
  and Event_Timestamp >= '2019-07-22') x
)

我认为这足够了吗

然后您可以运行以下命令:

select
*
from    dbo.fn_SelectQuery_AL()

让我知道它是否有效。