查询较新的记录时,缓慢查询存储过程

时间:2012-03-27 22:53:28

标签: c# asp.net sql sql-server sql-server-2008

对不起下面的文字墙...

我这里有一个奇怪的问题。我有一个很大的表,在过去几天存储来自Exchange 2007的邮件跟踪日志信息。记录数量为数百万(约合10-12百万),每30分钟一次,我通过PowerShell计划任务从所有传输服务器批量插入任何新登录。

每晚一次我运行一项维护任务来清除任何超过一天的日志,以便表格不会变得太大,但如果可以的话我想保留日志的时间更长。

该表名为MessageTracking,其主键为IDENTITY int列, [MessagelogID] ,每个记录增加1。

[日期 - 时间] 列的 [日期 - 时间] 列中有非聚集索引。

发件人和收件人字段中有一个全文索引。

用户可以通过我在C#Asp.net中编写的前端网页搜索表格。该页面允许使用4个搜索字段进行非常基本的搜索:

  • Start DateTime
  • 结束日期时间
  • 汇款人
  • 收件人

这会将查询传递给实际将记录拉回的存储过程。存储过程称为 GetMessageTracking

现在我的奇怪问题。此查询以0秒的形式返回结果,快速闪烁:

USE [DATABASENAME]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[GetMessageTracking]
        @maximumRows = 20,
        @startRowIndex = 0,
        @sortExpression = N'[date-time]',
        @SearchStartDate = N'2012-03-27 13:51',
        @SearchEndDate = N'2012-03-27 20:09',
        @SearchSender = N'user@domain.com',
        @SearchRecipient = N'Default'

SELECT  'Return Value' = @return_value

GO

如果我将@SearchStartDate参数更改为一小时,即 N'2012-03-27 14:51',那么它很长时间内都无法完成。

我只能假设我的日期时间索引存在重大问题,因为全文目录通常是空闲的。我遇到的挑战之一是我每小时插入数千条记录,索引( IX_DateTime )很快就会碎片化,但是我想不出一个很好的办法来阻止这种情况发生。

所以我的问题真的是双重的:

1)在搜索较新的记录时,如何查看导致此问题的问题?

2)当有大量插入时,有关索引的提示吗?

我想也许是执行计划造成这种奇怪的行为,但似乎没有。我尝试将WITH RECOMPILE选项添加到查询中,这完全没有任何区别。我清除了执行计划缓存也没有效果。

非常确定我的问题完全取决于我的索引。

谢谢!

3 个答案:

答案 0 :(得分:1)

使用重新编译是一个很好的第一步。所以我们可以排除参数嗅探问题的可能性。

请发布执行计划的屏幕截图。我想这个问题会变得清晰。我猜这是一个统计问题。查询优化器认为没有DateTime> = N'2012-03-27 14:51'的行,因此选择了错误的计划。尝试运行sp_updatestats。

关于问题的第2项:将索引填充设置为50-80范围内的某个值。

答案 1 :(得分:0)

由于INSERT和DELETE的数量很多,您可能在表上有碎片索引。以下脚本(取自SQL Authority)将为您提供有关碎片的信息

select object_name(i.object_id) as table_name,
       indexstats.avg_fragmentation_in_percent
from sys.dm_db_index_physical_stats(db_id(), null, null, null, 'detailed') indexstats
inner join sys.indexes i 
   on i.object_id = indexstats.object_id and i.index_id = indexstats.index_id
where indexstats.avg_fragmentation_in_percent > 20

如果发现大量碎片,则可以重建或重新组织索引。 SQL Authority还有另一个article,它提供以下信息。

索引重建:此过程会删除现有索引并重新创建索引。

alter index all on schema.table_name rebuild

索引重组:此过程在物理上重新组织索引的叶节点。

alter index all on schema.table_name reorganize

答案 2 :(得分:0)

我认为你已经确定了自己的问题 - 你正在做大量写作的指数碎片化。

您可以通过调整用于表和索引增长的填充(磁盘空间)来帮助缓解此问题。