因此,我在SQL Server 2008 R2中有一个查询(用作存储过程)。它有效,但我不敢相信没有更有效的方法。
数据在表“ ServiceInstance”中。这是一个完全平坦的表,每个IPAddress包含16个“实例”,每个实例具有用于该IPAddress的唯一TCPPort。
“ isRestarting”和“ isInuse”列对于该系统而言并不重要。当'isRestarting'或'isInUse'为True时,'IsAvailable'为False
列“ CPUId”为;每个服务器有4个CPU-我正在运行的Delhpi应用程序只能同时在一个CPU上有1个应用程序。因此,当使用IP为192.168.4.151的服务器上的CPU#1时,不允许从查询中返回该IP上的CPUId。(在一台具有4个核心的服务器上有16个实例)
)
因此,SP必须执行以下操作:
获取一个可用实例,该实例必须符合以下条件:
所以。利用这些信息,我创建了这个怪物:
UPDATE top(1) ServiceInstance
SET
LastRequestDate=GETDATE()
,IsInUse=1
,IsAvailable=0
OUTPUT
inserted.ServiceInstanceId,
inserted.IpAddress,
inserted.TcpPort,
inserted.LastRequestDate,
inserted.IsInUse
WHERE
ServiceInstanceId IN
(
SELECT Top (1) ServiceInstanceId FROM ServiceInstance
WHERE
(ServiceInstance.IsAvailable = 1 AND ServiceInstance.IsEnabled = 1)
AND ServiceInstanceId NOT IN
(
SELECT NGI1.ServiceInstanceId
FROM
(SELECT CpuId,IpAddress
FROM [ServiceInstance] NGI
WHERE IsInUse=1) a
INNER JOIN ServiceInstance AS NGI1 ON a.IpAddress = NGI1.IpAddress AND a.CpuId = NGI1.CpuId
)
ORDER BY LastRequestDate ASC
)
但是,我觉得这不是解决问题的最有效方法。该查询应该在监视时间内每秒运行约10次,因此目前对我的SQL Server造成了沉重的CPU压力。
欢迎任何提示!我觉得我应该可以使用PARTITION OVER或加入我自己的表,但是我似乎无法成功创建它...!
好的,表结构如下:
在这一刻,我没有索引。这是因为表发生了很多变化(每次使用ServerInstance时,表都会发生3或4次变化(1 =使用,2 =使用后重启,3 =设置IsAvailable,4 =失败时重启)我的猜测是,如果我创建了索引,则必须对每个突变进行更新。不确定,但是我觉得它会降低性能:)
执行计划:
进行一些负载测试后的重要补充:
我真的需要Exec @RC =sp_getapplock @Resource='MyLock', @LockMode='Exclusive', @LockOwner='Transaction', @LockTimeout = 1000
为此StoredProcedure使用。没有它就无法正常工作!
WITH UnAvailableCpus AS (
SELECT IpAddress
,CpuId
FROM ServiceInstance
WHERE IsAvailable = 0
GROUP BY IpAddress
,CpuId
)
,AvailableInstances AS (
SELECT ServiceInstanceId
,LastRequestDate
FROM ServiceInstance
LEFT JOIN UnavailableCpus
ON UnavailableCpus.IpAddress = ServiceInstance.IpAddress
AND UnavailableCpus.CpuId = ServiceInstance.CpuId
WHERE ServiceInstance.IsAvailable = 1
AND ServiceInstance.IsEnabled = 1
AND UnavailableCpus.IpAddress IS NULL
)
,PreferredInstance AS (
SELECT TOP 1 ServiceInstanceId
FROM AvailableInstances
ORDER BY LastRequestDate
)
UPDATE ServiceInstance
SET
LastRequestDate=GETDATE()
,IsInUse=1
,IsAvailable=0
OUTPUT
inserted.ServiceInstanceId
,inserted.IpAddress
,inserted.TcpPort
,inserted.LastRequestDate
,inserted.IsInUse
WHERE ServiceInstanceId IN (SELECT ServiceInstanceId FROM PreferredInstance)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句