优化/简化游标sql

发布于 2024-11-08 20:20:54 字数 1359 浏览 0 评论 0原文

我有下面的代码,它运行得很好,只需要几秒钟来计算答案 - 我想知道是否有更快/更简洁的方法来编写这段代码 - 如果是这样,我在做什么错误的?

谢谢

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

i've got the below code, and it operates just fine, only it takes a couple of seconds to calculate the answer - i was wondering whether there is a quicker/neater way of writing this code - and if so, what am i doing wrong?

thanks

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简单气质女生网名 2024-11-15 20:20:54

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

最好使用正确的联接并通过避免相关子查询(引用联接表中的值并且必须对该表的每一行执行的查询)来设计查询以仅执行每个部分一次。计算值是可以的,只要它们只计算一次 - 即从最终的 where 子句中计算。

下面是一个演示相关子查询的简单示例:

错误的 sql:

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

这里对每一行运行子选择,这会很慢,尤其是在 table2(d) 上没有索引的情况下

更好的 sql:

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

这里数据库最多会扫描每个表一次,速度会很快

It looks like this your sql was generated from a reporting tool. The problem is you are executing the SELECT top 1 dbo.matterdatadef.ptmatter... query for every row of table lamatter. Further slowing execution, within that query you are recalculating comparison values for both ptclient and LSCCert - values that aren't going to change during execution.

Better to use proper joins and craft the query to execute each part only once by avoiding correlated subqueries (queries that reference values in joined tables and must be executed for every row of that table). Calculated values are OK, as long as they are calculated only once - ie from within the final where clause.

Here is a trivial example to demonstrate a correlated subquery:

Bad sql:

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

Here the sub-select is run for every row, which will be slow, especially without an index on table2(d)

Better sql:

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

Here the database will scan each table at most once, which will be fast

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文