2017-09-02 59 views
0

使用SQL Server数据库,我有一些SQL代码试图从联合表中获取并且工作正常。SQL Server查询长时间联合使用和列查看

新的要求是将列添加到从视图读取的现有SQL语句。我运行了单独的SQL语句,添加新列后它们运行良好,并且聊天的时间比原始时间稍长。

现在试图运行所有的SQL语句与联合在一起,它永远在运行。

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 1 and condn 2 

union 

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 3 and condn 4 

union 

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 5 and condn 6 

有关优化此查询的任何建议吗?

+3

这不是一个查询......这是伪代码......“来自X,Y,Z”是ansi 89语法的3路笛卡尔乘积。这本身应该表现糟糕。最重要的是,相关的子查询“(来自view1的SELECT Col 5 ...”将对外部查询中的每一行执行一次......然后......你正在做3次.. 。而顶尖的樱桃是你使用UNION而不是UNION ALL的意思,这意味着你已经在混合中增加了一个独特的操作。你可能在这里有一个完美的风暴。 –

+1

[踢坏的习惯:用旧的 - 样式联接](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx) - 旧式*逗号在ANSI - ** 92 ** SQL标准(** 25年**之前)中,表*样式的分离列表被替换为* proper * ANSI'JOIN'语法,并且不鼓励使用它 –

+0

感谢您的回复。将更改为使用连接,如何更改newcol1以更好地执行使用上述我能够得到我需要的结果,但它的性能很差,请提供一个例子作为vladatr。 – user3761541

回答

1

很多人忽视的一件事是,UNION不仅仅会返回所有子查询行的联合,但它会检查重复项,所以它可能会减慢查询速度。如果要返回三个子查询的所有结果(包括重复项),则应使用通常速度更快的UNION ALL

例如,假设你得到这些结果来自单个子查询:使用UNION

Query 1 Query 2 Query 3 
------- ------- ------- 
1, 1, 1 1, 1, 1 4, 5, 6 
2, 2, 2 3, 3, 3 7, 8, 9 
1, 2, 3 3, 2, 1 1, 2, 3 
3, 2, 1    3, 2, 1 

您将获得:

1, 1, 1 
2, 2, 2 
1, 2, 3 
3, 2, 1 
3, 3, 3 
4, 5, 6 
7, 8, 9 

,并使用UNION ALL您将获得:

1, 1, 1 
2, 2, 2 
1, 2, 3 
3, 2, 1 
1, 1, 1 
3, 3, 3 
3, 2, 1 
4, 5, 6 
7, 8, 9 
1, 2, 3 
3, 2, 1 

如果你真的需要查询返回只有区别ct行,您可能需要在查询返回的列上添加索引,也许他们当前的查询依赖于由SQL Server创建的自动索引,并且这些更改使优化程序停止使用它们。

1

我建议重写整个查询:

SELECT col 1, col 2, col3, 
    case 
     when v.col5 = 'ee' 
      then 'xx' 
      else 'yy' end as newcol1 
FROM X 
INNER JOIN Y ON Y.??? = X.??? 
INNER JOIN Z ON Z.??? = X.??? 
LEFT OUTER JOIN view1 v ON v.id = X.id AND col5 = 'ee' 
WHERE (condn 1 and condn 2) 
    OR (condn 3 and condn 3) 
    OR (condn 5 and condn 6) 

这样的表X,Y,Z需要只能读取一次。