Sql 是我对“的理解”;选择distinct";对的
我们最近发现了一个系统的性能问题,我想我已经解决了,但我不确定我的理解是否正确 在最简单的形式中,我们有一个表Sql 是我对“的理解”;选择distinct";对的,sql,select,db2,performance,distinct,Sql,Select,Db2,Performance,Distinct,我们最近发现了一个系统的性能问题,我想我已经解决了,但我不确定我的理解是否正确 在最简单的形式中,我们有一个表blah,我们根据一个键字段将各种值累积到其中。基本形式是: recdate date rectime time system varchar(20) count integer accum1 integer accum2 integer 有比这多得多的累加器,但它们都是相同的形式。主键由recdate、rectime和system组成 当值被收集到表
blah
,我们根据一个键字段将各种值累积到其中。基本形式是:
recdate date
rectime time
system varchar(20)
count integer
accum1 integer
accum2 integer
有比这多得多的累加器,但它们都是相同的形式。主键由recdate
、rectime
和system
组成
当值被收集到表中时,给定的recdate/rectime/system
的计数将增加,该键的值将添加到累加器中。这意味着可以使用accumN/count
获得平均值
现在,我们还有一个关于该表的视图,具体如下:
create view blah_v (
recdate, rectime, system, count,
accum1,
accum2
) as select distinct
recdate, rectime, system, count,
value (case when count > 0 then accum1 / count end, 0),
value (case when count > 0 then accum2 / count end, 0)
from blah;
换句话说,视图给出的是累加器的平均值,而不是总和。它还确保在计数为零的情况下,我们不会得到被零除的结果(这些记录确实存在,我们不允许删除它们,所以不要麻烦告诉我它们是垃圾——你在向唱诗班布道)
我们注意到,执行以下操作之间的时间差:
select distinct recdate from XX
根据我们使用的是表还是视图,差异很大。我所说的区别是,表的时间是1秒,视图的时间是27秒(有100K行)
我们实际上跟踪到了选择distinct
。似乎正在发生的是,DBMS实际上正在加载其中的所有行并对它们进行排序,以便删除重复的行。这很公平,我们愚蠢地让它这么做
但我很确定视图包含主键的每个组件这一事实意味着无论如何都不可能有重复项。我们已经验证了这个问题,因为如果我们创建另一个没有distinct的视图,它将以与基础表相同的速度执行
我只是想确认我的理解,如果
select distinct
包含所有主键组件,则不能有重复项。如果是这样,那么我们可以简单地适当地更改视图。如果视图直接从单个表中选择,并且选定列的子集在表中是唯一的,那么所选行的值将是唯一的,而distinct是冗余的。是,如果包含了所有主要的关键元素,那么要求不同的结果是没有意义的
表的主键约束已经排除了这些列之间的重复项,但您的DBMS仍将处理元组以确保它们是不同的。在这种情况下,不同的字段对您没有任何好处,因为基础表上的主键约束已经保证了不同字段的唯一性。您可以尝试将视图重写为:
create view blah_v (
recdate, rectime, system, count,
accum1,
accum2
) as select
recdate, rectime, system, count,
case when count > 0 then accum1 / count else 0 end,
case when count > 0 then accum2 / count else 0 end,
from blah;
分享和享受