到目前为止,我已经找到了三种方法来实现这一目标,但我对这些方法的性能表示担忧,并希望知道哪种方法对性能更好.
第一种方法是使用a big case statement.这是一个包含3列的示例,基于上面链接中的示例.我的案例陈述会更长,因为我将查看6列.
Select Id,Case When Col1 <= Col2 And Col1 <= Col3 Then Col1 When Col2 <= Col3 Then Col2 Else Col3 End As TheMin From MyTable
第二个选项是使用UNION
operator with multiple select statements.我会把它放在一个接受Id参数的UDF中.
select Id,dbo.GetMinimumFromMyTable(Id) from MyTable
和
select min(col) from ( select col1 [col] from MyTable where Id = @id union all select col2 from MyTable where Id = @id union all select col3 from MyTable where Id = @id ) as t
我找到的第三个选项是use the UNPIVOT operator,直到现在我才知道它是不存在的
with cte (ID,Col1,Col2,Col3) as ( select ID,Col3 from TestTable ) select cte.ID,Col3,TheMin from cte join ( select ID,min(Amount) as TheMin from cte UNPIVOT (Amount for AmountCol in (Col1,Col3)) as unpvt group by ID ) as minValues on cte.ID = minValues.ID
由于表的大小以及查询和更新此表的频率,我担心这些查询对数据库的性能影响.
此查询实际上将用于连接到具有几百万条记录的表,但是返回的记录将一次减少到大约一百条记录.它将在一天中运行多次,我查询的6列经常更新(它们包含每日统计数据).我不认为我查询的6列上有任何索引.
在尝试获得最少的多列时,哪种方法更适合性能?或者还有另一种我不知道的更好的方法吗?
我正在使用sql Server 2005
样本数据&结果
如果我的数据包含这样的记录:
Id Col1 Col2 Col3 Col4 Col5 Col6 1 3 4 0 2 1 5 2 2 6 10 5 7 9 3 1 1 2 3 4 5 4 9 5 4 6 8 9
最终结果应该是
Id Value 1 0 2 2 3 1 4 4
解决方法
> 1记录:没有明显的差异
> 10条记录:无明显差异
> 1,000条记录:无明显差异
> 10,000条记录:UNION子查询速度稍慢. CASE WHEN查询比UNPIVOT查询快一点.
> 100,000条记录:UNION子查询明显变慢,但UNPIVOT查询比CASE WHEN查询快一点
> 500,000条记录:UNION子查询仍然明显变慢,但UNPIVOT变得比CASE WHEN查询快得多
所以最终的结果似乎是
>对于较小的记录集,似乎没有足够的差异.使用最容易阅读和维护的内容.
>一旦开始进入更大的记录集,UNION ALL子查询与其他两种方法相比开始表现不佳.
> CASE语句在某个点(在我的情况下,大约100k行)中执行最佳,并且UNPIVOT查询成为性能最佳的查询
由于您的硬件,数据库架构,数据和当前服务器负载,一个查询变得比另一个更好的实际数量可能会发生变化,因此如果您担心性能,请务必使用您自己的系统进行测试.
我还使用Mikael’s answer进行了一些测试;但是,它比大多数记录集大小的其他3种方法都要慢.唯一的例外是它比非常大的记录集大小的UNION ALL查询要好.我喜欢它除了显示最小值之外还显示列名的事实.
我不是dba,所以我可能没有优化我的测试并错过了一些东西.我正在测试实际的实时数据,因此可能会影响结果.我尝试通过运行每个查询几次来解释这一点,但你永远不会知道.如果有人写了一个干净的测试并分享他们的结果,我肯定会感兴趣.