2011-05-20 69 views
1

我已经得到了下面的代码,它运行得很好,只需要几秒钟来计算答案 - 我想知道是否有一个更快/更整洁的方式来编写此代码 - 如果是这样,我做错了什么?优化/简化游标sql

感谢

select case when 
    (select LSCCert from matterdatadef where ptmatter=$Matter$) is not null then 
    (
     (select case when 
      (SELECT top 1 dbo.matterdatadef.ptmatter 
      From dbo.workinprogress, dbo.MatterDataDef 
      where ptclient=(
       select top 1 dbo.workinprogress.ptclient 
       from dbo.workinprogress 
       where dbo.workinprogress.ptmatter = $matter$) 
       and dbo.matterdatadef.LSCCert=(
       select top 1 dbo.matterdatadef.LSCCert 
       from dbo.matterdatadef 
       where dbo.matterdatadef.ptmatter = $matter$) 
      )=ptMatter then (
       SELECT isnull((DateAdd(mm, 6, (
         select top 1 Date 
         from OfficeClientLedger 
         where (pttrans=3) 
          and ptmatter=$matter$ 
         order by date desc))), 
        (DateAdd(mm, 3, (
         SELECT DateAdd 
         FROM LAMatter 
         WHERE ptMatter = $Matter$))) 
      ) 
     ) 
     end 
     from lamatter 
     where ptmatter=$matter$) 
    ) 
    end 

回答

1

它看起来像这样你的SQL是从报告工具生成的。问题是您正在执行SELECT top 1 dbo.matterdatadef.ptmatter...查询lamatter的每行。进一步减慢执行,在该查询中,您将重新计算ptclient和LSCCert的比较值 - 在执行期间不会更改的值。

最好使用适当的连接和工艺的查询,以通过避免相关子(即在连接表参考值与必须为表的每一行被执行的查询)只执行一次每一个部分。计算值是可以的,只要它们只计算一次 - 即从最后的where子句中。

下面是一个简单的例子来说明一个相关子

不良的SQL:

select a, b from table1 
where a = (select c from table2 where d = b) 

在这里,子选择运行的每一行,这将是缓慢的,特别是不具有对表2的索引(d)

更好的SQL:

select a, b from table1, table2 
where a = c and d = a 

这里的数据库每次扫描最多一次,这将会很快