因此,我在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