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

时间:2012-02-22 15:38:23

标签: sql sql-server-2005 tsql

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

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 
    ..................
    .................
    ....................
    .................

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:4)

对于康拉德来说,

+1,因为他的回答可能就是你所需要的,我重复了他的一些语法。

Apply和CTE的问题是它们是针对a,b join中的每一行进行评估的。

我会创建两个临时表。表示最大行并在其上放置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 
       ..................
       .................

P.S。我正在为#TEMP探索TVP。 TVP支持PK并且开销比#tmp少。但我没有在这种类型的应用程序中进行头对头比较。

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