1

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

有没有更好的方法可以花费更少的时间让我达到同样的效果..?我需要随机值。

4

2 回答 2

1
  1. 表有名称索引吗?如果不应用它

2.MediaWiki 使用了一个有趣的技巧(对于 Wikipedia 的 Special:Random 功能):包含文章的表有一个带有随机数的额外列(在创建文章时生成)。要获得一篇随机文章,请生成一个随机数,并在随机数列中获取具有下一个更大或更小(不记得是哪个)值的文章。使用索引,这可以非常快。(而且 MediaWiki 是用 PHP 编写并为 MySQL 开发的。)

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

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

于 2012-06-17T05:13:32.787 回答
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 行确实很小)。

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

于 2012-06-17T06:45:42.667 回答