因此,我在SQL Server 2008 R2中有一个查询(我用它作为存储过程)。 它的工作原理,但我不能相信没有更有效的方法。SQL查询需要改进的性能(1个表)
数据在表'ServiceInstance'中。这是一个完全平坦的表,每个IPAddress包含'实例',它们中的每一个都具有用于该IP地址的唯一TCP端口。
列'isRestarting'和'isInuse'对这个系统并不重要; '二者isRestarting' 或 'isInUse' 是真中, 'IsAvailable' 是当假
列 'CPUID' 是;每个服务器有4个CPU - 并且我运行的Delhpi应用程序只能同时在一个CPU上有1个应用程序。因此,如果服务器上的IP为'192.168.4.151'的CPU#1正在使用,则该IP上的该CPUId不允许从查询返回。 (有4个核心一台服务器上16个实例)
)
因此,SP必须做到以下几点:
获取可用的情况下,它必须符合:
- SP应该总是返回1行。
- 这是一种低PRIO我大气压 - 如果需要,
- 的ServerInstance我可以重新运行SP“的IsEnabled必须是真实的
- 当返回ServerInstance,它必须被设置为” IsAvailable” =假,所以它不会再次,直到工作完成(复位由我的应用程序逻辑进行)
- 没有对IP相同的CPUID必须拾起‘IsAvailable =假’
- 这可确保该服务器上的CPU#空闲
- 尚未使用时间最长的ServerInstance是首选。
- 因为我有一个大水池,并希望实现流量负载均衡
- 在“发现” ServerInstance要立即更新。
- 的 'LastRequestDate' 要加盖
- 的 'IsInuse' 设置为true
- 的 'IsAvailable' 设置为假
所以。有了这些信息,我创造了这个怪物:
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
)
但是,我觉得这不可能是最有效的方式去做事情。 这个查询应该在peek小时每秒运行〜10次,因此目前会给我的SQL Server带来一些沉重的CPU压力。
欢迎任何提示!我觉得我应该能够使用PARTITION OVER或加入到我自己的桌子,但我似乎无法成功创建它...!
好了,所以,表结构如下:
- ServiceInstanceId INT NOT NULL
- IPAddres VARCHAR(20)NOT NULL
- 的TCPPort VARCHAR(5)NOT NULL
- LastRequestDate日期时间NOT NULL
- IsEnabled BIT NOT NULL
- IsAvailable BIT NOT NULL
- IsRestarting BIT NOT NULL
- IsInuse BIT NOT NULL
- CPU INT NOT NULL
在这一刻,我没有索引。这是因为表被每一个ServerInstance是 '使用' 3或4次 (1 = 使用,使用后2 = 重启表变异时间突变很多(,3 =设定IsAvailable,4 = 重新启动失败) 我的猜测是,如果我做索引,这将有充分的突变进行更新不知道,但我觉得这会降低性能:)
Exec的计划:
重要的一些loadtests后添加:
我真的需要使用Exec @RC =sp_getapplock @Resource='MyLock', @LockMode='Exclusive', @LockOwner='Transaction', @LockTimeout = 1000
对于这个StoredProcedure。如果没有它,效果不好!
您的查询中有错误:SET IsAvailable = 0 - 必须为1,如果您想'IsAvailable'设置为True – MikkaRin
不,只要从服务器中取出'ServerInstance',它就不可用。我的应用程序逻辑将在完成时将其设置为'可用':)。编辑:ive用这个信息更新我的文章,谢谢 – Samjongenelen
是不是'[NhgDocV40]。[dbo]。[ServiceInstance]'与ServiceInstance'不同?在第二个情节中,你的意思是16个实例是对的?而在最后一颗子弹中,你的意思是''IsAvailable'设置为False'? – NickyvV