如果你愿意通过BIGINT字段添加到表:
ALTER TABLE InvoiceQueue
ADD uuid BIGINT NULL DEFAULT NULL,
INDEX ix_uuid (uuid);
那么你可以先做更新,并选择记录更新,通过:
CREATE PROCEDURE pop_invoice_queue(IN compId int(11), IN limitRet int(11))
BEGIN
SET @uuid = UUID_SHORT();
UPDATE InvoiceQueue
SET uuid = @uuid,
lastPopDate = NOW()
WHERE companyid = compId
AND uuid IS NULL
AND (lastPopDate IS NULL OR lastPopDate < NOW() - INTERVAL 3 MINUTE)
ORDER BY
id
LIMIT limitRet;
SELECT *
FROM InvoiceQueue
WHERE uuid = @uuid
FOR UPDATE;
END;;
对于UUID_SHORT()函数返回唯一值,它应该被称为每台机器每秒不超过1600万次。请访问here了解更多详情。
出于性能考虑,你可能要改变lastPopDate场是NOT NULL为OR条款将导致您的查询不会使用索引,即使一个是可供选择:
ALTER TABLE InvoiceQueue
MODIFY lastPopDate DATETIME NOT NULL DEFAULT '0000-00-00';
然后,如果你这样做不是已经有一个,你可以在companyid/lastPopDate/uuid字段添加索引,如下所示:
ALTER TABLE InvoiceQueue
ADD INDEX ix_company_lastpop (companyid, lastPopDate, uuid);
然后你就可以删除从UPDATE查询子句:
UPDATE InvoiceQueue
SET uuid = @uuid,
lastPopDate = NOW()
WHERE companyid = compId
AND lastPopDate < NOW() - INTERVAL 3 MINUTE
ORDER BY
id
LIMIT limitRet;
将使用刚刚创建的索引。