在SQLServer2005中提高日志记录表的性能

在SQLServer2005中提高日志记录表的性能,sql,sql-server,sql-server-2005,tsql,performance,Sql,Sql Server,Sql Server 2005,Tsql,Performance,我有一个“历史记录”表,其中我将每个请求记录到我们网站上的Web处理程序中。以下是表格定义: /****** Object: Table [dbo].[HistoryRequest] Script Date: 10/09/2009 17:18:02 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[HistoryRequest]( [HistoryRequestID] [u

我有一个“历史记录”表,其中我将每个请求记录到我们网站上的Web处理程序中。以下是表格定义:

/****** Object:  Table [dbo].[HistoryRequest]    Script Date: 10/09/2009 17:18:02 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[HistoryRequest](
    [HistoryRequestID] [uniqueidentifier] NOT NULL,
    [CampaignID] [int] NOT NULL,
    [UrlReferrer] [nvarchar](512) NOT NULL,
    [UserAgent] [nvarchar](512) NOT NULL,
    [UserHostAddress] [nvarchar](15) NOT NULL,
    [UserHostName] [nvarchar](512) NOT NULL,
    [HttpBrowserCapabilities] [xml] NOT NULL,
    [Created] [datetime] NOT NULL,
    [CreatedBy] [nvarchar](100) NOT NULL,
    [Updated] [datetime] NULL,
    [UpdatedBy] [nvarchar](100) NULL,
 CONSTRAINT [PK_HistoryRequest] PRIMARY KEY CLUSTERED 
(
    [HistoryRequestID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[HistoryRequest]  WITH CHECK ADD  CONSTRAINT [FK_HistoryRequest_Campaign] FOREIGN KEY([CampaignID])
REFERENCES [dbo].[Campaign] ([CampaignId])
GO

ALTER TABLE [dbo].[HistoryRequest] CHECK CONSTRAINT [FK_HistoryRequest_Campaign]
GO
此语句上1050行37秒:

SELECT * 
  FROM HistoryRequest AS hr 
 WHERE Created > '10/9/2009'
 ORDER BY Created DESC
有没有人对加快这一进程有什么建议?我在PK上有一个聚集索引,在创建的列上有一个常规索引。我尝试了一个独特的索引,它吐出抱怨有一个重复的条目-这是可以预料的


欢迎有任何见解

对于日志表,您可能不需要uniqueidentifier列。您也不太可能对它进行查询,因此它不是一个很好的聚集索引候选对象。您的示例查询位于“Created”上,但没有索引。如果您经常查询“已创建”值的范围,那么它将是一个很好的聚类候选对象,即使它不一定是唯一的

OTOH,外键建议按活动进行频繁查询,在这种情况下,由该列进行聚类是有意义的,并且可能会更好地将插入的键分散到索引中-代理键和时间戳都会按顺序添加记录,随着时间的推移,插入的工作量会增加,因为节点扇区的填充不太随机


如果它只是一个日志表,为什么它有更新审核列?它通常是只写的。

对于日志表,您可能不需要uniqueidentifier列。您也不太可能对它进行查询,因此它不是一个很好的聚集索引候选对象。您的示例查询位于“Created”上,但没有索引。如果您经常查询“已创建”值的范围,那么它将是一个很好的聚类候选对象,即使它不一定是唯一的

OTOH,外键建议按活动进行频繁查询,在这种情况下,由该列进行聚类是有意义的,并且可能会更好地将插入的键分散到索引中-代理键和时间戳都会按顺序添加记录,随着时间的推移,插入的工作量会增加,因为节点扇区的填充不太随机


如果它只是一个日志表,为什么它有更新审核列?它通常是只写的。

嘿,我在大集合中拉XML列时看到一些奇怪的行为。尝试将索引放回已创建的索引上,然后在select语句中指定列;但是省略XML。看看这会如何影响结果的返回时间。

嘿,我看到了在大集合中拉XML列时的一些奇怪行为。尝试将索引放回已创建的索引上,然后在select语句中指定列;但是省略XML。查看这对结果返回时间的影响。

您正在请求非覆盖索引(已创建)上的所有列(*)。在大型数据集上,您可以保证找到聚集索引扫描比非聚集索引范围查找和书签查找更有效的位置

你需要一直吗?如果是,并且典型的访问模式是这样的,则必须相应地组织表,并使Created成为最左侧的聚集键


如果不是,那么考虑将查询更改为可覆盖查询,例如只选择HistoryRequestID和创建的,这些都由非聚集索引覆盖。如果需要更多字段,请将它们作为包含列添加到非聚集索引中,但要考虑到这将增加额外的存储空间和IO日志写入时间。

您正在请求非覆盖索引(已创建)上的所有列(*)。在大型数据集上,您可以保证找到聚集索引扫描比非聚集索引范围查找和书签查找更有效的位置

你需要一直吗?如果是,并且典型的访问模式是这样的,则必须相应地组织表,并使Created成为最左侧的聚集键


如果不是,那么考虑将查询更改为可覆盖查询,例如只选择HistoryRequestID和创建的,这些都由非聚集索引覆盖。如果需要更多字段,请将它们作为包含列添加到非聚集索引中,但要考虑到这将增加额外的存储空间和IO日志写入时间。

重建索引。在表名之后使用WITH(NOLOCK)子句。在适当的情况下,如果您希望对在实时环境中大量使用的表(如日志文件)运行长时间(ish)运行查询,则可能会应用此方法。这基本上意味着您的查询可能会丢失一些最新的记录,但您也没有在表上保持打开的锁,这会产生额外的开销。

重建索引。在表名之后使用WITH(NOLOCK)子句。在适当的情况下,如果您希望对在实时环境中大量使用的表(如日志文件)运行长时间(ish)运行查询,则可能会应用此方法。它基本上意味着您的查询会错过一些最新的记录,但是您也不会在表上持有一个锁打开-这会造成额外的开销。

也可以考虑在日期列上放置更频繁的簇。经常。我会玩这个。谢谢我拉出XML列并将其放入新创建的表(HistoryRequestExtended)中。这一行动释放了我的声明,它又回到了快速尖叫。(即使使用SELECT*“错误”)。谢谢!:)嘿,没问题。。。这就是为什么我们停止在我的店铺的SQL 2005数据库中使用XML数据类型的原因。相反,我们倾向于在ntext中存储数据,并在代码中完成所有XML工作。我们计划在几个月后发现SQL 2008是否有任何改进。我将对此进行研究。谢谢我拉出XML列并将其放入新创建的表(HistoryRequestExtended)中。这一行动释放了我的声明,它又回到了快速尖叫。(即使是“