[英]Performance Issue with SQL Server query in a stored procedure
使用Microsoft企业库3.0从.net应用程序(Windows服务)调用的存储过程,我们面临性能问题。 SQL Server过程仅检查记录的存在,如果不存在,则将记录插入表中,否则仅返回记录。
该表中包含以下列:
create table AlarmLog
(
Id bigint
MessageId int
MessageTime datetime
ControllerId int
InterfaceHardwareId int
IDType int
MapId int
RelatedEmployeeId int
RelatedCardId int
);
Id
列是主键,并且具有聚集索引。
作为业务规则,在插入记录时,我们需要确保组合( MessageId, MessageTime, ControllerId, InterfaceHardwareId, IDType, MapId
)是唯一的。 因此,我们放置一个if exists
条件来检查该组合是否已经存在。 这种状态检查要花费很长时间。
我们尝试在MessageId, MessageTime, ControllerId, InterfaceHardwareId, IDType, MapId
上添加非聚集索引。
在我们实验室的测试服务器上,大约有30,000,000条记录,即使条件适当,使用相同的.net服务,每分钟也会以大约400多行的速度插入。 我们还尝试添加上述非聚集索引,并发现了一些明显的改进。
在生产服务器上,大约有300,000条记录,并且当我们从.net应用程序(Windows服务)逐行插入条件时,每分钟仅插入10至20行。 如果删除条件检查,则每分钟插入的行数将达到300至400+行。 我们还尝试添加/删除上述非聚集索引,但未发现任何明显的改进。
因此,我们暂时将其禁用。 有趣的是,如果我们从SQL Server Management Studio运行存储过程以插入1条记录,则没有问题,我们还检查了实际的执行计划,没有进行表扫描,也没有花费任何时间。
还尝试了其他性能调整活动,包括重建,重新组织,更新统计信息,存储过程重新编译和参数嗅探。 但是,似乎没有任何效果。
我们现在已修复。 我们找不到其他选择。 如果您可以向我们提供一些建议/指导,将会很有帮助。
提前致谢。 乌贾尔
添加唯一约束而不是索引,如下所示:
alter table AlarmLog add constraint uq_alarmlog_row unique (
MessageId, MessageTime, ControllerId,
InterfaceHardwareId, IDType, MapId);
这将自动拒绝插入值与该列组合完全匹配的新行。
就性能而言,这也应该是快速的。 无需调用过程即可运行先前的select
并检查值是否存在。
只需运行一个简单的SQL insert
解决问题。
您的生产环境可能接近带宽上限。 由于当前正在运行其他操作。 正在处理的查询数量使您的网络饱和。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.