外部申请的替代方案是什么?

Use*_*404 3 sql t-sql sql-server-2005

最近我在我的查询中添加了外部应用.从那以后,这个查询需要永远.我知道它与之关联的表是现在数据库中最大的表的一个原因.

select   
    a.*,
    b.*,
    BTab.*,
    BTTab.*
from 
    tableA a 
    join tableB b ON a.ID = b.UID
    join *****
    left join *******
    ....
    ....
    ....
    outer apply 
        (SELECT TOP 1 * 
        FROM 
            biggestTable bt 
        WHERE 
            bt.id = a.id 
            and a.id <> 100 
        ORDER BY a.datetime desc) BTab
    Outer apply
        (SELECT TOP 1 * 
        FROM 
            biggestTable btt
        WHERE 
            btt.id = a.id 
            AND btt.DateTime <> '1948-01-01 00:00:00.000'
            and btt.value = 0 
        order by btt.datetime desc) BTTab
where 
    ..................
    .................
    ....................
    .................
Run Code Online (Sandbox Code Playgroud)

有没有比使用外部应用更好的解决方案?

Con*_*rix 7

这是一个替代方案,不能说它是否更好.您可能只需要在大表上使用更好的索引

WITH BTAB as 
(       SELECT TOP 1 
            * ,
            row_nubmer() over (partition by b.id) rn 

        FROM 
            biggestTable bt 
) ,
BTTab as (SELECT TOP 1 
              * ,
              row_nubmer() over (partition by btt.id order by btt.datetime desc) rn 
        FROM 
            biggestTable btt
        WHERE 
            AND btt.DateTime <> '1948-01-01 00:00:00.000'
            and btt.value = 0 
)

select   
    a.*,
    b.*,
    BTab.*,
    BTTab.*
from 
    tableA a 
    join tableB b ON a.ID = b.UID
    join *****
    left join BTab on ON a.ID = BTab.ID 
           and BTAB.rn = 1
    left join BTTabon ON a.ID = BTTab.ID 
           and BTTab.rn = 1
Run Code Online (Sandbox Code Playgroud)


pap*_*zzo 5

康拉德+1,因为他的答案可能就是你所需要的,我重用了他的一些语法。

Apply 和 CTE 的问题在于它们是针对 a、b 连接中的每一行进行评估的。

我会创建两个临时表。表示最大行并在其上放置 PK。好处是这两个昂贵的 quires 完成一次并且加入到 PK 中。加入PK的大好处。我吃掉#temp 的开销来获得单次评估和PK 很多。

   Create table #Btab (int ID PK, ...)
   insert into #Btab
   WITH BTAB as 
   (       SELECT * ,
               row_nubmer() over (partition by b.id) rn 
           FROM 
               biggestTable
           where ID <> 100 
   ) 
   Select * from BTAB
   Where RN = 1 
   order by ID

   Create table #Bttab (int ID PK, ...)
   insert into #Bttab
   WITH BTTAB as 
   (       SELECT * ,
               row_nubmer() over (partition by id order by datetime desc) rn 
           FROM 
               biggestTable
           where DateTime <> '1948-01-01 00:00:00.000' and value = 0
   ) 
   Select * from BTAB
   Where RN = 1 
   order by ID

   select   
       a.*,
       b.*,
       #Btab.*,
       #Bttab.*
   from 
       tableA a 
       join tableB b ON a.ID = b.UID
       join *****
       left join *******
       ....
       ....
       ....
       left outer outer join #Btab 
           on #Btab.ID = a.ID
       left outer outer join #Bttab 
           on #Bttab.ID = a.ID
   where 
       ..................
       .................
Run Code Online (Sandbox Code Playgroud)

PS我正在为此探索#TEMP上的TVP。TVP 支持 PK,并且开销比 #tmp 少。但是我没有在这种类型的应用程序中对它们进行正面比较。

通过#TEMP 测试 TVP 并获得了 1/2 秒的改进(大约是创建和删除临时表所需的时间)。