1

有一个报告,其查询在 where 子句中使用 isnull,这会导致一些性能问题。这是一个非常简化的示例。 http://www.sqlfiddle.com/#!6/79759/11

该查询使用多值参数,通常只返回一个或两个值。(我尝试使用 sqlfiddle 中的表变量复制 SSRS 多值参数)

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

有一个拥有所有产品的上部门。一些产品存在于一个子部门。如果它存在于较低的分区中,那就是应该显示的分区。

公司参数可以接受上级、下级或两者兼有。

关于如何更改查询以获得更好的性能的任何想法?

4

2 回答 2

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

这将非常高效。如果在顶部选择中找到匹配项,则应在底部选择中抑制它,因为它是联合而不是联合全部。注意 like 而不是 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 链接。之前没看到。这行得通。工会本身不会压制骗子,因为您也在选择部门,对不起。因此,您必须使用 not in 或者我更喜欢的 left outer where null。

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
于 2012-10-17T13:35:28.477 回答
1

我不确定,但是 cte 在您的情况下是否有效?

;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)
于 2012-10-16T19:08:10.910 回答