由于排名和列具有空值,SQL查询缓慢

时间:2014-08-14 07:07:30

标签: sql sql-server sql-server-2008

编辑:

我在数据库中有以下表格,其中包含 10百万记录:

声明:

create table PropertyOwners (
    [Key] int not null primary key,
    PropertyKey int not null, 
    BoughtDate DateTime, 
    OwnerKey int null, 
    GroupKey int null
)
go

[Key]是主键,PropertyKey,BoughtDate,OwnerKey和GroupKey的组合是唯一的。

使用以下索引:

CREATE NONCLUSTERED INDEX [IX_PropertyOwners] ON [dbo].[PropertyOwners] 
(
    [PropertyKey] ASC,
    [BoughtDate] DESC,
    [IsGroup] ASC
)
INCLUDE ( [OwnerKey], [GroupKey])
go

案例说明:

对于单个BoughtDate,一个属性可以属于多个所有者或单个组,对于单个记录,可以是OwnerKey或GroupKey但不能同时为两个,因此对于每个记录,其中一个属性为null。我试图使用以下查询OwnerKey从表中检索数据。如果所有者和组同时拥有相同的属性行而不是拥有OwnerKey的行,那么这就是我使用" IsGroup"在秩函数中。

declare @ownerKey int = 40000
select PropertyKey, BoughtDate, OwnerKey, GroupKey
from (  
    select PropertyKey, BoughtDate, OwnerKey, GroupKey,
        RANK() over (partition by PropertyKey order by BoughtDate desc, IsGroup) as [Rank]
    from PropertyOwners
) as result
where result.[Rank]=1 and result.[OwnerKey]=@ownerKey

当我使用任何PropertyKey / OwnerKey / GroupKey [Rank] = 1时,需要2-3秒才能获得记录。但是当我试图获取PropertyKey / OwnerKey / GroupKey的记录而不在同一查询中使用[Rank] = 1时,它正在以毫秒为单位执行。请参阅以下查询:

declare @ownerKey int = 40000
select PropertyKey, BoughtDate, OwnerKey, GroupKey
from (  
    select PropertyKey, BoughtDate, OwnerKey, GroupKey,
        RANK() over (partition by PropertyKey order by BoughtDate desc, IsGroup) as [Rank]
    from PropertyOwners
) as result
where result.[OwnerKey]=@ownerKey

我还尝试使用Indexed视图预先对它们进行排名,但我无法在查询中使用它,因为索引视图中不支持Rank函数。

请注意,此表每天更新一次并使用Sql Server 2008 R2。任何帮助都将是 非常感谢。

1 个答案:

答案 0 :(得分:1)

如果我正确理解了你的查询,它基本上如下:"对于给定的所有者,返回该所有者是最新的属性的所有属性"。

这也可以通过其他方式实现,无需对整个10M表进行排名,例如:

select po.*
from dbo.PropertyOwners po
where po.OwnerKey = @OwnerKey
  and not exists (
  select 0 from dbo.PropertyOwners lo
  where lo.PropertyKey = po.PropertyKey
  and lo.BoughtDate > po.BoughtDate
  -- Other group-related conditions here, if need be
  );

基本上相同,只是有点不同的措辞:

select po.*
from dbo.PropertyOwners po
  left join dbo.PropertyOwners lo on lo.PropertyKey = po.PropertyKey
  and lo.BoughtDate > po.BoughtDate
  -- Other group-related conditions here, if need be
where po.OwnerKey = @OwnerKey
  and lo.PropertyKey is null;

你肯定需要不同的指数,我不能确定他们会有所帮助。但至少试一试。