在我的 jsp 应用程序中,我有一个搜索框,允许用户在数据库中搜索用户名。我在每次击键时发送一个 ajax 调用,并从输入的字符串开始获取 5 个随机名称。我正在使用以下查询:
select userid,name,pic from tbl_mst_users where name like 'queryStr%' order by rand() limit 5
但这非常慢,因为我的表中有超过 2000 条记录。
有没有更好的方法可以花费更少的时间让我达到同样的效果..?我需要随机值。
在我的 jsp 应用程序中,我有一个搜索框,允许用户在数据库中搜索用户名。我在每次击键时发送一个 ajax 调用,并从输入的字符串开始获取 5 个随机名称。我正在使用以下查询:
select userid,name,pic from tbl_mst_users where name like 'queryStr%' order by rand() limit 5
但这非常慢,因为我的表中有超过 2000 条记录。
有没有更好的方法可以花费更少的时间让我达到同样的效果..?我需要随机值。
2.MediaWiki 使用了一个有趣的技巧(对于 Wikipedia 的 Special:Random 功能):包含文章的表有一个带有随机数的额外列(在创建文章时生成)。要获得一篇随机文章,请生成一个随机数,并在随机数列中获取具有下一个更大或更小(不记得是哪个)值的文章。使用索引,这可以非常快。(而且 MediaWiki 是用 PHP 编写并为 MySQL 开发的。)
如果结果数字分布不均,这种方法可能会导致问题;IIRC,这已在 MediaWiki 上修复,因此如果您决定这样做,您应该查看代码以了解它当前是如何完成的(可能他们会定期重新生成随机数列)。
3.http://jan.kneschke.de/projects/mysql/order-by-rand/
“非常慢”有多慢,以秒为单位?
您的查询可能很慢的原因很可能是您没有在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 提供的链接非常有趣。它描述了一种性能几乎恒定的解决方案。唯一的缺点是它一次只返回一个随机行。