Sha*_*yan 43 sql database queue sql-server-2008
我想使用数据库表作为队列.我想插入其中并以插入的顺序(FIFO)从中获取元素.我主要考虑的是性能,因为我每秒都有成千上万的这些交易.所以我想使用一个SQL查询,它给我第一个元素而不搜索整个表.我读的时候不会删除一行.SELECT TOP 1 .....帮忙吗?我应该使用任何特殊索引吗?
Ada*_*Dev 32
我将使用IDENTITY字段作为主键,为每个排队项提供唯一递增的ID,并在其上粘贴聚簇索引.这将表示项目排队的顺序.
要在处理项目时将项目保留在队列表中,您需要一个"状态"字段来指示特定项目的当前状态(例如0 =等待,1 =正在处理,2 =处理).这是防止项目被处理两次所必需的.
处理队列中的项目时,您需要找到当前未处理的表中的下一个项目.这将需要以这样的方式,以便防止多个进程同时处理同一个项目,如下所示.请注意,该表提示您在实现队列时应注意的UPDLOCK和READPAST.
例如在一个sproc中,像这样:
DECLARE @NextID INTEGER
BEGIN TRANSACTION
-- Find the next queued item that is waiting to be processed
SELECT TOP 1 @NextID = ID
FROM MyQueueTable WITH (UPDLOCK, READPAST)
WHERE StateField = 0
ORDER BY ID ASC
-- if we've found one, mark it as being processed
IF @NextId IS NOT NULL
UPDATE MyQueueTable SET Status = 1 WHERE ID = @NextId
COMMIT TRANSACTION
-- If we've got an item from the queue, return to whatever is going to process it
IF @NextId IS NOT NULL
SELECT * FROM MyQueueTable WHERE ID = @NextID
Run Code Online (Sandbox Code Playgroud)
如果处理某个项目失败,您希望以后能够再次尝试吗?如果是这样,您需要将状态重置为0或其他.这需要更多的思考.
或者,不要将数据库表用作队列,但是像MSMQ这样的东西 - 只是想我会把它扔进混合中!
如果不删除已处理的行,那么您将需要某种标志,指示已经处理了一行.
在该标志上放置一个索引,并在您要订购的列上.
将表分区到该标志上,因此出列的事务不会堵塞您的查询.
如果你真的1.000
每秒都会收到消息,那么每天会产生86.400.000
一行.您可能想要想办法清理旧行.
一切都取决于您的数据库引擎/实现。
对我来说,带有以下列的表上的简单队列:
id / task / priority / date_added
Run Code Online (Sandbox Code Playgroud)
通常有效。
我使用优先级和任务对任务进行分组,如果任务加倍,我选择优先级更高的任务。
不要担心 - 对于现代数据库来说,“数千”并不是什么特别的。
归档时间: |
|
查看次数: |
38589 次 |
最近记录: |