首页 > 解决方案 > 使用 PHP mt_rand() 代替 MySQL rand() 以避免慢查询

问题描述

我有一个 PHP 文件,它从 MySQL 数据库中查找随机 id,但是当表足够大时,它会变慢。 ID 行有间隙。

原来的

$sql = "SELECT * FROM definiciones ORDER BY rand() LIMIT 1";

主意

$random = mt_rand(0, 10000);
$sql = "SELECT * FROM definiciones WHERE id = (SELECT max(id) FROM definitiones WHERE id < $random)";

我事先知道数据库中的确切行数。替换原始查询是个好主意吗?

标签: phpmysql

解决方案


替换原始查询是个好主意吗?

是的,但有一种更简单的表达方式:

SELECT * FROM definiciones WHERE id >= ? ORDER BY id LIMIT 1

设置为 0和?表中最大 ID 之间的随机数。


现在,一个改进:如果 的值有任何差距,id以前方法的结果会有些偏差。(例如,如果没有带有 的行id < 100,那么带有 的行id = 100将比带有 的行更频繁地被选择id = 101。)您可以通过使用单独的列进行随机化来避免这种情况。首先,您需要添加列:

ALTER TABLE definiciones ADD COLUMN randomval FLOAT NOT NULL,
                         ADD KEY randomval (randomval);
UPDATE TABLE definiciones SET randomval = RAND();

然后,选择一个公平选择的随机项目:

SELECT * FROM definiciones WHERE randomval > ? LIMIT 1;

使用 0 到 1 之间的随机值作为参数。

这很有可能不会返回任何行(如果RAND()选择的值大于表中的最大值)。如果发生这种情况,请重复查询。

您需要在randomval = RAND()向表中插入新行时进行设置。


推荐阅读