编辑:
我在数据库中有以下表格,其中包含 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。任何帮助都将是 非常感谢。
答案 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;
你肯定需要不同的指数,我不能确定他们会有所帮助。但至少试一试。