2012-10-16 33 views
1

存在一個報告,其查詢在where子句中使用isnull,並導致一些性能問題。 這是一個非常簡單的例子。 http://www.sqlfiddle.com/#!6/79759/11提高在where子句中使用isnull的性能

查詢使用多值參數,通常只返回一個或兩個值。 (我試圖複製在sqlfiddle使用表變量SSRS多值PARAM)

select 
    isnull(descrL,descr) as division, 
    product 
from Upper 
left join Lower on product = productL 
where isnull(DescrL,Descr) in (@params) 

有具有所有產品上分裂。一些產品存在於兒童部門。如果它存在於低級分區中,那就是應該顯示的分區。

公司參數可以接受上部分部,下部分部或兩者。

有關如何改變查詢以獲得更好性能的任何想法?

+0

報告的產品是否始終必須來自上表,即使在Lower中找到說明匹配? – iruvar

+0

是的,這兩個部門是相關的。有關該產品的信息僅在上表中提供。 – Gabe

+0

兩張表中有多少條記錄? – RThomas

回答

2
select descrL as division, product 
from Lower 
where DescrL like @params + '%' 
union 
Select descr, product 
from Upper 
where Descr like @params = '%' 

這將是非常高性能的。如果在頂部選擇中找到匹配,則應該在底部選擇中將其禁用,因爲它是聯合而不是全部聯合。注意類似的而不是in。如果你做了一個in,那麼就沒有辦法在DescrL或Descr上使用索引來查找結果。如果你喜歡,索引使用得很好。你可能不得不調整你的應用程序邏輯來完成這項工作。

如果你不能這樣做,那麼有這個解決方案。你必須添加fn_split到你的數據庫。 http://msdn.microsoft.com/en-us/library/aa496058(v=sql.80).aspx

select descrL as division, product 
    from Lower l 
    join dbo.fn_Split(@params, ',') p1 
     on l.DescrL = p1.value 
    union 
    Select descr, product 
    from Upper u 
    join dbo.fn_Split(@params, ',') p2 
     on u.Descr = p2.value 

如果你真的想勉強維持業績的最後一點,你可以聲明表變量,只爲了填充表變量運行一次fn_split,然後使兩個連接是在表變量。因此,在這裏您還可以利用列上的索引,這是您快速查詢所需的主要內容。運行時總是要在sql server中包含「實際執行計劃」,並查看結果並確保您看到索引查找而不是表掃描。

編輯:我去了你的sqlfiddle鏈接。之前沒有看到它。這工作。工會本身不會壓制愚蠢,因爲你也選擇師,對不起。所以你必須使用一個不在,或者如我所願,一個左外部空的地方。

select descrL as division, productL as product 
    from Lower l 
    join @params p1 
     on l.DescrL = p1.division 
    union 
    Select u.descr, u.product 
    from Upper u 
    join @params p2 
     on u.Descr = p2.division 
    left join (select productL as product 
       from Lower l2 
       join @params p3 
       on l2.DescrL = p3.division) sub1 
    on u.product = sub1.product 
     where sub1.product is null 
order by 2 
1

我不確定,但會在你的情況下工作嗎?

;with BothDivs as 
(
    select 
    isnull(descrL,descr) as division, 
    product 
    from Upper 
    left join Lower on product = productL 
) 
select division, product 
from BothDivs 
where division in (@params)