查询较新记录时,使用存储过程查询速度较慢
本文关键字:查询 存储过程 速度 新记录 | 更新日期: 2023-09-27 18:29:23
对不起下面的文字墙。。。
我有一个奇怪的问题。我有一个相当大的表,其中存储了过去几天Exchange2007中的邮件跟踪日志信息。记录数以百万计(约10-120万),每30分钟我会通过PowerShell计划任务从所有传输服务器批量插入一次新日志。
每天晚上我都会执行一次维护任务,清除超过一天的日志,这样桌子就不会太大,尽管如果可以的话,我想把日志保存更长时间。
该表名为MessageTracking,它有一个主键,即IDENTITY int列,[MessagelogID],每条记录递增1。
[date-time]asc的[date-time][strong>列上有一个非聚集索引。
"发件人"answers"收件人"字段上有一个全文索引。
用户可以通过我在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选项添加到查询中,但没有任何区别。我也清除了执行计划缓存,但没有任何效果。
很确定我的问题完全是由于我的索引。
谢谢!
使用重新编译是一个很好的第一步。因此,我们可以排除参数嗅探的可能性,如果问题。
请张贴执行计划的屏幕截图。我想这样问题就会变得很清楚。我猜想这是一个统计问题。查询优化器认为不存在DateTime>=N'2012-03-27 14:51'的行,并因此选择了错误的计划。请尝试运行sp_updatestats。
至于你的第二个问题:将索引填充设置为50-80之间的某个值。
由于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权威机构的另一篇文章提供了以下信息。
索引重建:此过程删除现有索引并重新创建索引。
alter index all on schema.table_name rebuild
索引重新组织:此过程物理地重新组织索引的叶节点。
alter index all on schema.table_name reorganize
我认为您已经发现了自己的问题——索引的碎片化和您正在进行的大量编写。
您可以通过调整表和索引增长所需的填充(磁盘空间)来帮助缓解这个问题。