对不起下面的文字墙...
我这里有一个奇怪的问题。我有一个很大的表,在过去几天存储来自Exchange 2007的邮件跟踪日志信息。记录数量为数百万(约合10-12百万),每30分钟一次,我通过PowerShell计划任务从所有传输服务器批量插入任何新登录。
每晚一次我运行一项维护任务来清除任何超过一天的日志,以便表格不会变得太大,但如果可以的话我想保留日志的时间更长。
该表名为MessageTracking,其主键为IDENTITY int列, [MessagelogID] ,每个记录增加1。
[日期 - 时间] 列的 [日期 - 时间] 列中有非聚集索引。
发件人和收件人字段中有一个全文索引。
用户可以通过我在C#Asp.net中编写的前端网页搜索表格。该页面允许使用4个搜索字段进行非常基本的搜索:
这会将查询传递给实际将记录拉回的存储过程。存储过程称为 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选项添加到查询中,这完全没有任何区别。我清除了执行计划缓存也没有效果。
非常确定我的问题完全取决于我的索引。
谢谢!
答案 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)
我认为你已经确定了自己的问题 - 你正在做大量写作的指数碎片化。
您可以通过调整用于表和索引增长的填充(磁盘空间)来帮助缓解此问题。