【发布时间】:2018-05-31 18:46:16
【问题描述】:
我们正面临使用 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,00,000 条记录,即使条件到位,它也使用相同的 .net 服务以每分钟大约 400 多行的速度更快地插入。我们还尝试添加上述非聚集索引,并发现了一些明显的改进。
- SQL Server 版本:SQL Server 2008 Standard
- .NET Framework 4.0
- 操作系统:Windows Server 2012 R2 标准版
在生产服务器上,大约有 300,000 多条记录,当我们从具备条件的 .net 应用程序(Windows 服务)逐行插入时,它每分钟仅插入 10 到 20 行。如果我们删除条件检查,那么插入的行数将达到每分钟 300 到 400+ 行。我们还尝试添加/删除上述非聚集索引,但没有发现任何明显的改进。
因此,我们暂时将其禁用。有趣的是,如果我们从 SQL Server Management Studio 运行存储过程以插入 1 条记录,则没有问题,我们还检查了实际执行计划,没有发生表扫描,存储过程也没有花费任何时间。
- SQL Server 版本:SQL Server 2012 Standard SP3
- .NET Framework 4.0
- 操作系统:Windows Server 2012 R2 标准版
还尝试了其他性能调整活动重建、重组、更新统计信息、存储过程重新编译和参数嗅探。但是,似乎没有任何效果。
我们现在正在修复中。我们找不到任何替代方案。如果您能给我们一些建议/指导,将会很有帮助。
提前致谢。 乌贾尔
【问题讨论】:
-
您忘记发布 SQL 语句了!没有查询,我们无法帮助您更快地进行查询!!! :) 表和索引的 DDL 也会帮助人们(不要列出列,提供
CREATE语句)。您还可以使用Paste the plan 提供实际执行计划 -
如果您注意到生产代码和在 SSMS 中运行代码之间的性能差异,请查看sommarskog.se/query-plan-mysteries.html。
-
只是猜测,但可能会将唯一索引扩展到包括
Id,比如将其放在(Id, MessageId, MessageTime, ControllerId, InterfaceHardwareId, IDType, MapId)上可能值得一试。
标签: c# sql sql-server windows service