我正在运行SQL Server 2012,这一个查询正在破坏我的数据库性能。
我的短信提供程序不支持预定的短信,所以我有一个短信引擎,它从数据库中获取消息并在预定的时间发送。我把这个查询放在一起,从数据库中获取消息,并且还改变它们的状态,以便它们不会再被拾取。
查询工作正常,它只会导致CPU的等待时间,特别是因为它每隔一秒运行一次。我安装了一个数据库性能软件,它说这个查询占实例执行时间的92%。该软件还表示,每次执行都会进行347,267次逻辑读取。
有关如何使其表现更好的任何想法?
我可以选择进入临时表并在返回之前更新这些结果吗?
以下是当前查询:
UPDATE TOP (30) dbo.Outgoing
SET Status = 2
OUTPUT INSERTED.OutgoingID, INSERTED.[Message], n.PhoneNumber, c.OptInStatus
FROM dbo.Outgoing o
JOIN Numbers n on n.NumberID = o.NumberID
LEFT JOIN Contacts c on c.ContactID = o.ContactID
WHERE Scheduled <= GETUTCDATE() AND SmsId IS NULL AND Status = 1
此查询涉及三个表:Outgoing,Numbers,&amp;联系人
Outgoing是此查询处理的主表。现在只有两个索引,OutgoingID上的聚簇主键索引[PK,bigint,not null]和SmsId [varchar(255),null]上的非聚集,非唯一索引,它是从在系统中成功接收消息后,我们的文本消息提供程序。 Status列只是一个与一些不同状态(Scheduled,Queued,Sent,Failed等等)相关的整数列
Numbers只是一个简单的表格,我们存储唯一的手机号码,该号码的一些不同格式,以及识别客户的一些基本信息,如名字,运营商等。它只有NumberID上的群集主键索引[BIGINT]。 PhoneNumber列只是一个varchar(15)。
“联系人”表格仅将个人(电话号码)与我们的某个商家联系起来,并保持号码的选择状态以及与客户/商家关系相关的其他信息。与此查询相关的唯一列是OptInStatus [bit,not null]和ContactID [PK,bigint,not null]
- UPDATE -
在Outgoing表上添加了一个非聚集索引,其中包含列(Scheduled,SmsId,Status),这似乎已将执行时间从2秒减少到毫秒。我将在明天检查我的性能监控软件,看看它是如何改进的。感谢大家到目前为止的帮助!
答案 0 :(得分:1)
正如一些评论者已经指出你需要dbo.Outgoing
表上的新索引。服务器正在努力寻找要更新/输出的行。这很可能是问题所在:
WHERE Scheduled <= GETUTCDATE() AND SmsId IS NULL AND Status = 1
要提高性能,您应该在dbo.Outgoing
上创建包含这些列的索引。这将使Sql Server更容易找到正确的行。另一方面,它会为实际更新创建更多的工作,因为在更新时会有一个需要注意的新索引。
当您正在努力解决此问题时,缩短SmsId
列可能是个好主意,除非您实际需要它长度为255个字符。最好在创建索引之前。
作为替代解决方案,您可能会考虑为传出的消息和 outgone 的消息分别创建表。然后你可以:
Outgoing
的所有记录插入Outgone
Outgoing
中的所有记录,并使用与您当前正在执行的输出子句。确保insert
和delete
操作在一个事务中完成,否则您很快就会在数据库中出现奇怪的不一致。
答案 1 :(得分:0)
它只是导致CPU的等待时间,特别是因为它每隔一秒运行一次。
摆脱TOP 30
并且每隔一秒运行一次,而不是每隔一秒......也许每两到三分钟。
答案 2 :(得分:-2)
您可以启用sql server的最大并行度以加快处理速度