我对此查询有疑问....或者,我还没有尽快。目前表' marketingDatabase'是大约11k行,但在下个月内,它可能接近10万行,到3月份可能增加到500k。
我知道使用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'。
答案 0 :(得分:3)
首先,看看我们是否可以稍微优化该查询:
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
只是一个想法......
答案 1 :(得分:0)
我们遇到了与您现在面临的问题相同的问题,即行数增长过高,rand()的顺序实际上导致连接挂起并抛出白页,因此我们必须提出不同的解决方案。
我们采取的一个选项是将1000个组中的ID分块并将它们放入缓存中,然后我们将随机选择我们选择的组,然后随机选择要从组中选择的ID。
我们还每天一次写一个平面文件的随机ID样本并从中读取数字,但我相信我们已经从以前的缓存解决方案的解决方案中解脱出来。
只是一些想法。