快速mysql查询,随机选择N个用户名

时间:2012-06-17 04:59:40

标签: mysql

在我的jsp应用程序中,我有一个搜索框,允许用户在数据库中搜索用户名。我在每次击键时发送一个ajax调用,并从输入的字符串开始获取5个随机名称。 我使用以下查询: select userid,name,pic from tbl_mst_users where name like 'queryStr%' order by rand() limit 5 但这很慢,因为我的表中有超过2000条记录。

有没有更好的方法,花费更少的时间,让我实现相同的...?我需要随机值。

2 个答案:

答案 0 :(得分:1)

  1. 表有名称索引吗? 如果不适用
  2. 2.MediaWiki使用了一个有趣的技巧(对于维基百科的特殊:随机特征):带有文章的表格有一个带有随机数的额外列(在创建文章时生成)。要获得一篇随机文章,请生成一个随机数,并获得随机数列中下一个更大或更小(不记得哪个)值的文章。使用索引,这可以非常快。 (MediaWiki是用PHP编写的,是为MySQL开发的。)

    如果结果数字分布不均,这种方法可能会导致问题; IIRC,这已在MediaWiki上修复,所以如果您决定这样做,您应该查看代码以了解它当前是如何完成的(可能它们会定期重新生成随机数列)。

    3.http://jan.kneschke.de/projects/mysql/order-by-rand/

答案 1 :(得分:1)

“非常缓慢”的速度有多慢,只需几秒钟?

您的查询可能很慢的原因很可能是您没有在name上放置索引。 2000行应该是MySQL可以处理的一块蛋糕。

另一个可能的原因是SELECT子句中有许多列。我假设在这种情况下,MySQL引擎在排序这个大的结果集之前首先将所有这些数据复制到临时表。

我建议以下内容,以便您尽可能长时间使用索引:

SELECT userid, name, pic
FROM tbl_mst_users
JOIN (
    -- here, MySQL works on indexes only
    SELECT userid
    FROM tbl_mst_users
    WHERE name LIKE 'queryStr%'
    ORDER BY RAND() LIMIT 5
) AS sub USING(userid); -- join other columns only after picking the rows in the sub-query.

此方法有点更好,但仍然无法很好地扩展。但是,对于小型表来说应该足够了(2000行确实很小)。

link provided by @user1461434非常有趣。它描述了一种性能几乎恒定的解决方案。唯一的缺点是它一次只返回一个随机行。