mysql优化:从一列唯一值中选择一个先前未选择的随机不同值对

问题描述 投票:2回答:1

从一列唯一(非重复)值中选择一对非先前选择的不同随机值的最有效方法是什么?

我目前的方法是(将每对值保持在一个单独的“mytable_associations”表中):

SELECT * FROM
(
 SELECT id,count(*) AS associations_count FROM mytable 
 INNER JOIN mytable_associations 
 WHERE (myvalue=myvalue1 OR myvalue=myvalue2) 
 GROUP BY myvalue 
 HAVING associations_count<(SELECT count(*) FROM mytable)-1
 ORDER BY rand() limit 1
) mytable1 
LEFT JOIN 
(SELECT myvalue AS myvalue2 FROM mytable) mytable2
ON mytable1.myvalue1<>mytable2.myvalue2
WHERE
(
 SELECT myvalue1 FROM mytable_associations 
 WHERE
 myvalue1=mytable1.myvalue1 AND myvalue2=mytable2.myvalue2
 OR
 myvalue1=mytable2.myvalue2 AND myvalue2=mytable1.myvalue1
) IS NULL;

(然后当然用这个新协会更新mytable_associations)

正如您所看到的,可以通过一些优化获得巨大收益。

(抱歉代码中的缩进很差,我真的不知道如何缩进mysql命令)。

你能帮助我吗?

(P.S.这是我在这里发布的第一个问题:当然我做了很多错事,我明白随之而来的火焰,但请不要太难我;))

mysql sql select random
1个回答
2
投票

涉及order by rand()的任何解决方案都将效率低下。有关替代方案,请参阅

要排除你已经选择过的数字,我就是这样做的(这是伪代码):

$c1 = SELECT COUNT(DISTINCT myvalue) FROM mytable
$c2 = SELECT COUNT(*) FROM mytable_associations

$offset = ROUND( RAND() * ($c1 * ($c1-1) - $c2) )

SELECT v.* FROM (
  SELECT LEAST(m1.myvalue,my2.myvalue) AS myvalue1,
    GREATEST(m1.myvalue,my2.myvalue) AS myvalue2
  FROM (SELECT DISTINCT myvalue FROM mytable) AS m1 
  INNER JOIN (SELECT DISTINCT myvalue FROM mytable) AS m2
    ON m1.myvalue <> m2.myvalue
) AS v
LEFT OUTER JOIN mytable_associations AS a USING (myvalue1,myvalue2)
WHERE a.myvalue1 IS NULL
LIMIT 1 OFFSET $offset

通过确保myvalue1 <myvalue2并在mytable_associations中按顺序存储它们,您可以简化连接。

© www.soinside.com 2019 - 2024. All rights reserved.