2012-02-22 123 views
3

最近我在我的查詢中添加了outer apply。從那以後,這個查詢就會一直存在我知道與之相關的表格是數據庫中最大的表格的原因之一。外套的替代方案是什麼?

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

有沒有比使用outer apply更好的解決方案?

+0

顯然我在這裏失去了一些東西。我對APPLY的瞭解是調用一個表值函數,但你沒有TVF。 APPLY在這個查詢中做了什麼?這是否就像內聯TVF? – Paparazzi 2012-02-22 17:18:40

+1

@BalamBalam - OP有兩個相關的子查詢。兩者都是以'a.id'作爲參數的Inline TableValuedFunctions。 – MatBailie 2012-02-22 17:21:38

回答

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 
4

+1康拉德作爲他的答案可能是你所需要的,我再利用他的一些語法。

Apply和CTE的問題是它們針對a,b連接中的每一行進行評估。

我會創建兩個臨時表。代表最大行並在其上放置PK。這樣做的好處是這兩個昂貴的問題一次完成,並且加入到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秒的改進(大約需要創建和刪除臨時表的時間)。

相關問題