适用于“仅插入”架构的SQL Server索引

时间:2014-04-10 13:12:42

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

我们正在使用SQLServer 2008,并且只有#34;仅插入"许多表的架构。

我们拥有的那种表的一个例子(这只是一个例子):

create table spotquotes
(
   Id numeric(19,0) identity(1,1) not null primary key clustered,
   feeditem_id numeric(19,0) not null,
   value_ask float not null,
   value_bid float not null,
   effectiveDateUTC datetime not null default getutcdate()
)

然后我们使用此查询查询表

select * from spotquotes q
inner join
    (select feeditem_id, max(id) as latest from spotquotes group by feeditem_id) q2
    on q.id = q2.latest and q.feeditem_id = q2.feeditem_id

事实上,创建上述查询的视图是有意义的:

create view latestspotquotes as
select * from spotquotes q
inner join
    (select feeditem_id, max(id) as latest from spotquotes group by feeditem_id) q2
    on q.id = q2.latest and q.feeditem_id = q2.feeditem_id

即。我们想要"最新的"为每个feeditem_id插入表中 - 但我们也能够在过去的任何时候查询表的状态(这对审计考虑非常好)。

更简单的方法。我希望优化以下查询:

select feeditem_id, max(id) as latest from spotquotes group by feeditem_id

这个表通常有数亿行 - 但是少数feeditem_id实例很可能位于表的末尾。

使用现有的主键,此表中约有1亿行, SQLServer 2008需要6秒才能执行此查询 - 它非常慢。

所以我想知道 - 如果我们要为这个表创建一个索引来加速这个查询,我们应该创建什么索引?

可悲的是,管理工作室没有为我们建议索引。

编辑:仍有问题,但我会提出一个单独的问题。

更新

通过使用"交叉应用"可以从SQL服务器中哄骗更快的查询(< 10 ms)。与Id desc的select top * ...顺序相结合。有关详细信息,请参阅Convincing SQL server to search backwards on clustered index for an insert only schema

2 个答案:

答案 0 :(得分:1)

仅插入索引:S我只有精简插入模式最好不带任何索引,但在表上有任何索引会损害插入操作的性能。

如何在feeditem_ideffectiveDateUTC字段上创建索引,如

CREATE NONCLUSTERED INDEX NIX_feeditem_id_effectiveDateUTC
ON dbo.spotquotes(feeditem_id ASC, effectiveDateUTC DESC)
GO

现在写一下你的查询......

;WITH LastestRecords
 AS(
   SELECT Id 
        ,feeditem_id 
        ,value_ask
        ,value_bid
        ,effectiveDateUTC
        ,ROW_NUMBER() OVER (PARTITION BY feeditem_id ORDER BY ffectiveDateUTC DESC) AS RN
  FROM spotquotes
  )
 SELECT Id 
        ,feeditem_id 
        ,value_ask
        ,value_bid
        ,effectiveDateUTC
 FROM LastestRecords
 WHERE RN = 1

按如下方式创建索引

CREATE NONCLUSTERED INDEX NIX_feeditem_id_Id
ON dbo.spotquotes(feeditem_id ASC, ID DESC)
GO

<强>查询

;WITH LastestRecords
 AS(
   SELECT Id 
        ,feeditem_id 
        ,value_ask
        ,value_bid
        ,effectiveDateUTC
        ,ROW_NUMBER() OVER (PARTITION BY feeditem_id ORDER BY Id DESC) AS RN
  FROM spotquotes
  )
 SELECT Id 
        ,feeditem_id 
        ,value_ask
        ,value_bid
        ,effectiveDateUTC
 FROM LastestRecords
 WHERE RN = 1

答案 1 :(得分:0)

对于此查询:

select feeditem_id, max(id) as latest from spotquotes group by feeditem_id

创建以下非聚集索引

CREATE INDEX IX_Spotquotes_feeditem_id on spotquotes(feeditem, id)