Sql server 2008 高效的TSQL查询

Sql server 2008 高效的TSQL查询,sql-server-2008,tsql,Sql Server 2008,Tsql,有没有更有效的方法编写这个SQL查询 它在大约45秒内从一组100000行中返回大约800行 我正在使用SQLServer2008R2 Select a.Div as Division ,a.Room as RoomLocation ,a.Form as Forms ,a.Nums as TotalNumberLocations From AView a Where a.Id = '1' And a.Div = 'A' Group By a.Div, a.Nu

有没有更有效的方法编写这个SQL查询

它在大约45秒内从一组100000行中返回大约800行

我正在使用SQLServer2008R2

Select a.Div as Division
      ,a.Room as RoomLocation
      ,a.Form as Forms
      ,a.Nums as TotalNumberLocations
From AView a
Where a.Id = '1'
And a.Div = 'A'
Group By a.Div, a.Nums, a.Room, a.Form

union

Select b.Div as Division
      ,b.Room as RoomLocation
      ,b.Form as Forms
      ,b.Nums as TotalNumberLocations
From AView b
Where b.Id = '1'
And b.Div = 'G'
Group By b.Div, b.Nums, b.Room, b.Form

union

Select c.Div as Division
      ,c.Room as RoomLocation
      ,c.Form as Forms
      ,c.Nums as TotalNumberLocations
From AView c
Where c.Id = '1'
And c.Div = 'R'
Group By c.Div, c.Nums, c.Room, c.Form
Order By Forms asc, TotalNumberLocations asc

如果可以在in子句中包含值,为什么要使用UNION?你扫描了桌子三次

Select Div as Division
      ,Room as RoomLocation
      ,Form as Forms
      ,Nums as TotalNumberLocations
From AView 
Where Id = '1'
And Div IN ('A','G','R')
Group By Div, Nums, Room, Form
Order By Forms asc, TotalNumberLocations asc
与类似,但是您也可以将
组替换为
不同的

Select distinct Div as Division
      ,Room as RoomLocation
      ,Form as Forms
      ,Nums as TotalNumberLocations
From AView a
Where Id = '1'
And Div in ('A', 'G', 'R')
Order By Forms asc, TotalNumberLocations asc

我假设在表
AView
Id
列和
Div
列上建立索引对该查询的性能非常有益,可能比重新编写查询更有益。

为什么不只做
其中Id='1'和Div in('A','G','R')
,另外,我也不明白为什么要使用
分组方式
,您可能希望使用
不同的
。在这种情况下,您根本不需要一个并集,但一般来说,如果您知道结果集不会重叠(在这种情况下,Div不能同时是a和G),并且并集的每个分支都不能生成重复的结果集(在这种情况下,由您的团队消除),您应该使用UNION ALL,而不是UNION。UNION可能更昂贵,因为它必须引入排序或类似的操作来删除所有集合中的重复项。是
AView
一个表,还是一个视图,顾名思义?在后一种情况下,它的定义是什么?我通常不会使用除非你有很多嵌套的OR语句,否则它就是同一个表。这就是UNION通常表现得更好的时候。这是我的经验。+1虽然
DISTINCT
而不是
GROUP BY
可能更清楚。@MartinSmith好吧,当你只需要DISTINCT值时,可以使用DISTINCT。但我不想完全改变原始代码。毕竟,这并不是问题的本质所在,在这种情况下,GROUP BY和DISTINCT在性能方面都会产生类似的执行计划。不过,我同意cleaner。这需要进行测试,我见过SQL Server 2008中的
UNION
版本比()
。语义是相同的,但计划并不总是保证完全相同。我很确定我见过这样的情况,即操作的这一部分发生在不同的点上(当然,我现在在我的复制中找不到任何东西)@FrankPI我认为这可能适用于做非常不同事情的联合。在这种情况下,我发现很难相信在同一个表中使用相同where子句和不同参数的三个联合会比In()等价物表现更好,除非还有其他事情(如三个过滤索引,或基于Div的分区,或大量其他未知数)。如果
Id
是一个int pass,请确保您的类型匹配。如果
Id
是一个int pass,那么它将
1
而不是
'1'
,如果
Div
是一个
nvarchar
字符串应该是
N'a',N'G',N'R'
,否则您可能得不到索引的好处。@ScottChamberlain尽管实际上这两个示例都不会阻止索引使用。
int
的数据类型优先级高于varchar,因此
'1'
将转换为
1
nvarchar
的数据类型优先级高于
varchar
@MartinSmith,我之所以这样说,是因为参数类型是
varchar
,但列和索引是
nvarchar
,@ScottChamberlain-情况正好相反。一个
varchar
列和
nvarchar
参数。那么你添加了两个索引了吗?我建议添加一个包含两个列的组合索引,因为这对这个查询来说是最有效的。