我遇到了这个查询的问题....或者,还没有我很快就会遇到的问题。目前,“marketingDatabase”表大约有 11,000 行,但在下个月内,它可能会接近 100,000 行,到 3 月可能会增长到 500,000 行。
我知道使用 ORDER BY RAND() 不是可行的方法,但这是我唯一需要做的事情。我尝试过其他方法,但第一个 WHERE 语句似乎让我失望了。我正在使用 PHP,所以我也可以用 PHP 处理其中的一些内容。
对于此查询,从适合 WHERE 语句的行中选择随机行的最佳方法是什么?
这是查询:
SELECT id
FROM `marketingDatabase`
WHERE do_not_call != 'true'
AND status = 'Pending'
AND install_id = 'AN ID HERE'
AND NOT EXISTS(
SELECT recordID
FROM reminders rem
WHERE rem.id = marketingDatabase.id
)
ORDER BY rand()
LIMIT 1
关于如何使这项工作更好的想法?我只需要一个随机的“id”。
最佳答案
首先,看看我们是否可以稍微优化一下该查询:
SELECT `m`.`id`
FROM `marketingDatabase` AS `m`
LEFT JOIN `reminders` AS `r` ON ( `r`.`id` = `m`.`id` )
WHERE
`m`.`do_not_call` != 'true'
AND `m`.`status` = 'Pending'
AND `m`.`install_id` = 'AN ID HERE'
AND `r`.`id` IS NULL
ORDER BY
rand()
LIMIT 1
注意:这只是一个想法,还没有在野外进行过测试。
为什么不计算可能要查找的记录数,然后使用 PHP 从该计数中找到一个随机行号,然后重新查询以找到它。
$rowCount = 0;
$rowCountSql = "SELECT COUNT(*) AS `rowcount`
FROM `marketingDatabase` AS `m`
LEFT JOIN `reminders` AS `r` ON ( `r`.`id` = `m`.`id` )
WHERE
`m`.`do_not_call` != 'true'
AND `m`.`status` = 'Pending'
AND `m`.`install_id` = 'AN ID HERE'
AND `r`.`id` IS NULL";
if( $rowCountRes = mysql_query( $rowCountSql )
&& mysql_num_rows( $rowCountRes )
&& $r = mysql_fetch_assoc( $rowCountRes ) )
$rowCount = $r['rowcount'];
$oneRow = false;
$oneRowSql = "SELECT `m`.`id` AS `rowid`
FROM `marketingDatabase` AS `m`
LEFT JOIN `reminders` AS `r` ON ( `r`.`id` = `m`.`id` )
WHERE
`m`.`do_not_call` != 'true'
AND `m`.`status` = 'Pending'
AND `m`.`install_id` = 'AN ID HERE'
AND `r`.`id` IS NULL
LIMIT ".(int) $rowCount.", 1";
if( $oneRowRes = mysql_query( $rowCountSql )
&& mysql_num_rows( $oneRowRes )
&& $r = mysql_fetch_assoc( $oneRowRes ) )
$oneRow = $r['rowid'];
这可能证明没有性能优势,但我只是想我会把它放在那里看看我更有学识的同事是否可以改进它。
对上述内容的进一步探索(如果我可以访问您的数据库,我将对其进行测试...)
SELECT `m`.`id` AS `rowid`
FROM `marketingDatabase` AS `m`
LEFT JOIN `reminders` AS `r` ON ( `r`.`id` = `m`.`id` )
WHERE
`m`.`do_not_call` != 'true'
AND `m`.`status` = 'Pending'
AND `m`.`install_id` = 'AN ID HERE'
AND `r`.`id` IS NULL
LIMIT ( FLOOR( RAND( ) * (
SELECT COUNT(*) AS `rowcount`
FROM `marketingDatabase` AS `m`
LEFT JOIN `reminders` AS `r` ON ( `r`.`id` = `m`.`id` )
WHERE
`m`.`do_not_call` != 'true'
AND `m`.`status` = 'Pending'
AND `m`.`install_id` = 'AN ID HERE'
AND `r`.`id` IS NULL ) ) ) , 1
只是一个想法...
关于php - 优化随机记录查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8033028/