简体   繁体   中英

Select a random row based on a requirement from 50k rows table. Too slow. How can I speed it up?

I have a table with about 50k rows. There's a column called status . Its value can be either 0 or 1 . I need to grab a random row that has status = 0 .

SELECT * FROM table WHERE status = 0 ORDER BY RAND() LIMIT 1 is obviously too slow.

So, what I did so far was, get the count of the amount of rows that have status = 0 using SELECT COUNT(status) FROM table WHERE status = 0

Now I now that I have 209 rows that have status = 0 , but how can I work on these rows?

I'd would like to order these 209 rows, and make my php script get a random row number between the numbers 0 and 209, but I'm not sure how I can achieve that..

Did you try this?

SELECT t.*
FROM table t
WHERE status = 0
ORDER BY RAND()
LIMIT 1;

Sorting 209 should be quite fast.

EDIT:

Getting a random value efficiently is challenging. If you have an index on table(status) , you can try an approach like this:

SELECT t.*
FROM table t cross join
     (select count(*) as allcnt from table where status = 0) const
WHERE status = 0 and
      RAND() < 10/allcnt
ORDER BY RAND()
LIMIT 1;

The rand() in the where clause is quite fast ( RAND() is fast, sorting is slow). It should greatly reduce the number of rows to an expected value of 10 -- which means that you are almost certain to get a row (99.99+%, I think) when you run it. This is also simpler than the variable method.

The variable method involves a subquery, which incurs its own overhead for reading and writing the derived table. The idea is to enumerate the rows and then choose one index randomly:

SELECT t.*
FROM (select t.*, @rn := @rn + 1 as rn
      from table t cross join
           (select @rn := 0, @rand := rand()) const
      where status = 0
     ) t cross join
     (select count(*) as allcnt from table where status = 0) const
WHERE floor(1 + @rand * const.allcnt) = rn;

我知道这需要两个查询,但是您可以尝试一下并对其进行基准测试:获取与status = 0匹配的行的总数,从PHP获取一个介于0和number-1之间的随机数,并使用限制1和php生成的随机值的偏移量。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM