【问题标题】:mysql optimization: select a non previously selected random pair of different values from a column of unique valuesmysql优化:从唯一值列中选择一个非先前选择的随机不同值对
【发布时间】:2012-01-05 21:06:18
【问题描述】:

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

我目前的方法是(将已经关联的每对值保存在单独的“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. 这是我在这里发布的第一个问题:当然,我做错了很多事情,我会理解随之而来的燃烧,但请不要对我太苛刻;))

【问题讨论】:

  • 理解您的查询似乎有点棘手。您是否介意对其进行一些深入了解,例如解释查询的不同部分以及它们的作用?如果你能给出一个你想要实现什么的虚拟例子,那就太好了
  • 基本上它是两个部分:首先我选择一个尚未相互耦合的值。我通过 SELECT RANDOM FROM mytable WHERE (SELECT number of associations for each value FROM associates_table)
  • 刚刚进行了更新以减少代码混乱。希望它现在更具可读性,但无论如何看看下面 Bill Karwin 的解决方案,这正是我想要的

标签: mysql sql select random


【解决方案1】:

任何涉及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

【讨论】:

  • 不使用 rand() 的顺序绝对是一种改进,但关于第 3 点,我看不出“WHERE a.myvalue1 IS NULL”如何避免重复选择 (a,b) 然后 ( b,a),当我尝试运行它时,我收到一个错误,说未知列 myvalue1(也试过 a.myvalue1 和 mytable_associations.myvalue1,都把它变成了语法错误)。我应该将这两种组合都添加到关联表中以防止这种情况吗?当我尝试运行导致此错误的解决方案时,我可能做错了什么?
  • (顺便说一句,非常感谢您的快速回复:我刚开始使用 SQL,有时很难弄清楚如何正确完成工作)
  • 抱歉,我误读了您原始问题中的查询,并且误解了您的表结构。我已经重写了我的答案。
  • 太棒了!清晰有效的解决方案。你是个奇才,非常感谢你的帮助!
猜你喜欢
  • 2021-01-11
  • 2012-03-27
  • 1970-01-01
  • 2016-03-22
  • 2016-10-25
  • 1970-01-01
  • 2021-07-08
  • 2012-01-24
  • 1970-01-01
相关资源
最近更新 更多