从结果集中选择一个随机行,以便在没有订单的情况下通过RAND()进行更新

时间:2013-10-12 17:32:20

标签: mysql sql random transactions database-performance

此过程是此目标应用程序中最常访问的过程。假设并发操作,并且t.value总是在变化。

-- Table is MySQL InnoDB
-- let's call this MainSelect
SELECT t.Id
FROM table t
WHERE t.A = conditionA AND t.B = conditionB AND t.value > 0
ORDER BY RAND()
LIMIT 1 INTO vIndex FOR UPDATE;

-- IF vIndex THEN
UPDATE table SET value = value - 1 WHERE id = vIndex

目标是修改此查询以使用this method of random row selection形式的速度。这里是为了完整性。这是这篇文章的主要问题。

SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

讨论:

MainSelect中的总行数将如何确定?

如果答案是生成MainSelect子查询,将FOR UPDATE移动到最外层查询,则在外部SELECT使用FOR UPDATE锁定行之前,随机选择的行的t.value可能变为0。类似的东西:

SELECT * FROM (firstquery) s ...random selection logic.. FOR UPDATE;

如果这种考虑是准确的,那么就会在一开始就设置哪个交易级别的问题。

由于

修改 - 工作时注释:

  1. 也许http://en.wikipedia.org/wiki/Reservoir_sampling,因为计数未知。我希望避免高隔离级别,因为我预计会降低吞吐量。

  2. 也许可以存储和索引随机数,而不是计算。然后选择一个随机数,根据limit documentation,随机选择一个非常快。这个问题是结果集不一致。

  3.   

    如果将LIMIT row_count与ORDER BY一起使用,则MySQL将排序结束为   很快它找到了排序结果的第一个row_count行,   而不是整理整个结果。如果订购是通过使用   索引,这非常快。

0 个答案:

没有答案