我想使用数据库表作为队列.我想插入它,并以插入顺序(FIFO)从中提取元素.我主要考虑的是性能,因为我每秒有数千个这样的事务.所以我想使用一个SQL查询,它在不搜索整个表的情况下为我提供第一个元素.我阅读时不会删除一行.

推荐答案

我会使用一个标识字段作为主键, for each 排队的项目提供唯一递增的ID,并在其上粘贴一个聚集索引.这将表示项目排队的顺序.

要在处理项目时将其保留在队列表中,需要一个"状态"字段来指示特定项目的当前状态(例如,0=等待,1=正在处理,2=已处理).这是为了防止一个项目被处理两次.

处理队列中的项目时,需要在表中查找当前未处理的下一个项目.这需要防止多个流程同时处理同一个项目,如下所示.请注意,在实现队列时,应该注意table hints UPDLOCK和READPAST.

e、 g.在一次大爆发中,类似这样的事情:

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

如果处理项目失败,是否希望稍后再试?如果是这样,您需要将状态重置为0或其他.这需要更多的思考.

或者,不要使用数据库表作为队列,而是使用类似MSMQ的东西——我只是想把它放在组合中!

Sql相关问答推荐

Oracle SQL对列进行汇总并在列表底部显示总计

如何嵌套两条SQL语句

PostgreSQL 9.6嵌套的INSERT/RETURN语句的CTE性能低得令人无法接受

获得第三名或最老的记录

基于是否具有某些数据的关联表覆盖SELECT语句中的列值

如何用HeidiSQL在Firebird中设置超时?

删除行而不使数据库超载

如何向 mariadb 添加外键?

用替代方案替换 SQL Cursor 以提高性能

返回给定日期后的第 4 个工作日(不包括公众假期)

复制行并根据 Oracle SQL 中其他表的值更改值

Oracle PL/SQL长期运行问题

带聚合函数的 percentile_cont

使用给定的变量对在循环中执行更新语句

如何显示最常引用条目的详细信息

PostgreSQL:通过数组的元素从另一个表中 Select 数据,然后按顺序显示

Django only() 和 values() 不适用于 prefetch_related()

SQLite 中的过滤运行总和视图

在 MS Access 中连接相关记录

包含多行的 SQL 查询