We have a queue organized with a table on MS SQL Server 2014:
CREATE TABLE [queue].[Messages](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Status] [tinyint] NOT NULL,
[Data] [nvarchar](max) NOT NULL,
[CreationDateUtc] [datetime] NOT NULL
)
CREATE NONCLUSTERED INDEX [IX_Messages_Status] ON [queue].[Messages]
([Status] ASC)
Stored procedure to send message:
ALTER PROCEDURE [queue].[SendMessage]
@MessageBody NVARCHAR(MAX),
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [queue].[Messages]
(
Data,
)
VALUES
(
@MessageBody,
)
END
And a stored procedure to receive messages:
ALTER PROCEDURE [queue].[ReceiveMessage]
AS
BEGIN
SET NOCOUNT ON;
UPDATE TOP (1) m
SET
m.Status = 2,
m.StartDateUtc = GETUTCDATE()
OUTPUT
INSERTED.*
FROM [queue].[Messages] m WITH (UPDLOCK, READPAST)
WHERE m.Status = 1
END
This stored procedure executes every second to check new messages in queue.
Very often we get blocks (PAGELATCH_EX
) on this query even if the queue is empty:
First idea was - diff-backups, but they are scheduled at different times:
Other queries don't make blocks so often.
- Am I right that this is due to
UPDLOCK
andREADPAST
hints? - Are there other reasons?
UPDATE TOP (1)
with no discernibleORDER BY
- you know that yourUPDATE
is arbitrary and non-deterministic, right? So it might be trying to update the latest row instead of the earliest row? You might want to change your implementation a little bit.