Sql server 加入内部视图非常慢

Sql server 加入内部视图非常慢,sql-server,tsql,Sql Server,Tsql,如果你能为我的问题想出一个更好的标题,请随意编辑我的帖子 在我开始之前,请记住以下几点: 我无法实现任何观点 我不能创建任何索引 select t1.*中的所有列都将被进一步使用,由于某些原因,这部分的速度会减慢 我有一个观点。此视图通常在30秒内完成 现在,这个视图至少需要2小时(2小时后我放弃并取消了查询) 这是我的密码: 耗时30秒的查询1: select t1.*, t2.legacysystemid as Servicerateid from NONW

如果你能为我的问题想出一个更好的标题,请随意编辑我的帖子

在我开始之前,请记住以下几点:

  • 我无法实现任何观点

  • 我不能创建任何索引

  • select t1.*
    中的所有列都将被进一步使用,由于某些原因,这部分的速度会减慢

  • 我有一个观点。此视图通常在30秒内完成

    现在,这个视图至少需要2小时(2小时后我放弃并取消了查询)

    这是我的密码:

    耗时30秒的查询1:

    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和t2.businessunit根据某些标准为空

    我能做些什么来加速加入?连接空值是否会降低性能

    编辑:

    我发现,在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])

    一切又开始超高速运转了


    现在我只需要想一想我怎样才能既吃蛋糕又吃蛋糕

    对于case语句,您可以检查是否更快,因为它们仅使用一个case,而每个case语句使用其他case,例如

    ,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]
    
    
    我在10英里记录中发现的时差最小

    /*1000万条记录的案例陈述*/
    SQL Server执行时间:CPU时间=3407毫秒, 运行时间=3404毫秒

    /*相同1000万条记录的即时if*/
    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
    

    问题与我的案例陈述有关:

    在我的一些专栏中,我有一个有点选择性的案例陈述(见我原来的帖子)。我还有一个类似的案例陈述作为我的加入标准

    我是如何通过使用以下格式解决问题的:

    with everything as (
    
    select *
    from table
    where criteria is not matched
    
    union all
    
    select *
    from same_table_as_above
    where criteria is matched
    
    )
    
    …我其余的问题

    我所做的主要工作是将符合特定标准的记录与不符合特定标准的记录分开,然后将它们合并在一起

    通过这样做,我可以回到30秒的查询,同时得到我想要的结果

    换句话说,我拿到了蛋糕,也吃了

    问题现在解决了

    编辑:

    通过这样做,我改变了执行计划。我不是执行计划方面的专家,但我知道这就是为什么我的变化更快的原因