如果您可以为我的问题找到一个更好的标题,请随时编辑我的帖子。
在开始之前,请记住以下几点:
我无法实现任何视图
我无法创建任何索引
select t1.*
中的所有列都在继续使用,由于某种原因,这部分速度变慢了。
我有一个看法。该视图过去需要30秒才能完成。
现在,此视图至少需要2个小时(2个小时后我放弃并取消了查询)。
这是我的代码:
查询1耗时30秒:
select
t1.*,
t2.legacysystemid as Servicerateid
from
NONWAIVER_RATES as t1
left join
v_SERVICERATE as t2 on t1.service = t2.service
and t1.fundingsource = t2.fundingsource
and t1.provider = t2.provider
and t1.businessunit = t2.businessunit
and t1.startdate = t2.startdate
and t1.enddate = t2.enddate
where
t2.service is not null
查询2花费了超过2个小时的时间:
与查询1完全相同,除了
t2.provider and t2.businessunit is NULL
根据某些条件。
该如何加快加入速度?加入NULL值会降低性能吗?
编辑:
我发现在v_servicerate视图中,我使用了case语句。
case
when lu_service.[iswaivereligible] = 0 AND lu_service.[isvariablerate] = 0
then NULL
else t1.[fprovider]
end as [provider]
--------------------------------------------
case
when lu_service.[iswaivereligible] = 0 AND lu_service.[isvariablerate] = 0
then NULL
else t1.[businessunit]
end as [businessunit]
-------------------------------------------------------------------------
case
when lu_service.[iswaivereligible] = 0 AND lu_service.[isvariablerate] = 0
then NULL
else t1.[providerid_parent]
end as [providerid_parent]
---------------------------------------------------
case
when lu_service.[iswaivereligible] = 0 AND lu_service.[isvariablerate] = 0
then NULL
else t1.[providerid_child]
end as [providerid_child]
-----------------------------------------------------------------
如果我删除case语句并仅使用列本身(又名[providerid_parent],[providerid_child],[provider]和[businessunit])
一切再次变得超级快。
现在,我只需要弄清楚如何才能拿到我的蛋糕并将其吃掉。 。
答案 0 :(得分:1)
对于case语句,您可能会检查iif()是否更快,因为它们仅在其他情况下使用一种情况,例如
,case
when lu_service.[iswaivereligible] = 0 AND lu_service.[isvariablerate] = 0 then NULL
else t1.[fprovider]
end as [provider]
-- becomes
,iif(lu_service.[iswaivereligible] = 0 AND lu_service.[isvariablerate] = 0,null,t1.[fprovider]) [provider]
我发现时差有1000万条记录,收益微乎其微。/ * 1000万条记录的案情声明* /
SQL Server执行时间:CPU时间= 3407 ms, 经过的时间= 3404毫秒。/ *如果相同的一千万个记录,则立即显示* /
SQL Server执行 时间:CPU时间= 3297毫秒,经过的时间= 3366毫秒。
关于视图的第一个想法。既然您发现案例陈述有问题,那么其中的某些想法就变得毫无意义了:)但是这里是
--first, updatestats then check execution time
exec sp_updatestats;
GO
-- next, I'd set "with schemabinding" and see if it's faster
create view blah with schemabinding
as
select
t1.*,
t2.legacysystemid as Servicerateid
from
NONWAIVER_RATES as t1
left join
v_SERVICERATE as t2
on
t1.service=t2.service
and t1.fundingsource=t2.fundingsource
and t1.provider=t2.provider
and t1.businessunit=t2.businessunit
and t1.startdate=t2.startdate
and t1.enddate=t2.enddate
where
t2.service is not null
GO
-- next I'd rework the join a bit, trying, not likely to work. sql should do this or something better "behind the scenes"
create view blah
as
t1.*,
t2a.Servicerateid
from
NONWAIVER_RATES as t1
left join
(select
t2.fundingsource
,t2.provider
,t2.businessunit
,t2.startdate
,t2.enddate
,t2.legacysystemid as Servicerateid
from
NONWAIVER_RATES as t1
inner join
v_SERVICERATE as t2
on
t1.service=t2.service -- if service is null it cannot match any value, even null.
and t1.fundingsource=t2.fundingsource
and t1.provider=t2.provider
and t1.businessunit=t2.businessunit
and t1.startdate=t2.startdate
and t1.enddate=t2.enddate
where
t2.service is not null ) t2a
on
t1.service=t2a.service
and t1.fundingsource=t2a.fundingsource
and t1.provider=t2a.provider
and t1.businessunit=t2a.businessunit
and t1.startdate=t2a.startdate
and t1.enddate=t2a.enddate
GO
答案 1 :(得分:0)
问题与我的案例陈述有关:
我在某些专栏中有一个案例陈述,但有些选择性(请参阅我的原始帖子)。我的加入条件也有类似的案例陈述。
我解决问题的方法是使用以下格式:
with everything as (
select *
from table
where criteria is not matched
union all
select *
from same_table_as_above
where criteria is matched
)
...其余查询。 。
关于我正在做的事情的主要构想是将符合特定条件的记录和不符合特定条件的记录分开,然后将它们合并在一起。
通过这种方式,我可以返回30秒的查询,同时获得所需的结果。
换句话说,我也把蛋糕也吃了。
问题现已解决。
编辑:
通过这种方式,我更改了执行计划。我不是执行计划方面的专家,但是我知道这就是为什么我的更改更快的原因。