SQL 中最快的加权概率 table 设计

Fastest weighted probability table design in SQL

我有一个 table 如下所示:

Id (int), Input (string), Output (string)

给定一些输入 X,我需要能够得到一个随机输出 Y,但根据 X-Y 在 table 中出现的频率进行加权。

以下是一些示例行:

 1. In1, Out1
 2. In1, Out2
 3. In1, Out2
 4. In2, Out3
 5. In2, Out4

所以在这种情况下,对于 'In1',我可能随机生成的输出是 Out1 或 Out2。生成 'Out2' 的可能性是两倍,因为 In1-Out2 转换在数据库中发生两次,而 In1-Out1 仅出现一次。对于 In2,将以相等的概率生成 Out3 或 Out4。

以下哪个选项的性能更高? (或者我忽略了第三种方法)

  1. 复制输入和输出值相同的行

然后我们只进行一次 SQL 调用:(取决于 mysql 或 mssql)

select * from table where Input = X order by rand() limit 1;
select top 1 * from table where Input = X order by NEWID();
  1. 在table
  2. 中存储输入X到输入Y的频率

所以现在 table 多了一个列:Frequency

之前的 table 看起来像这样:

 1. In1, Out1, 1
 2. In1, Out2, 2
 3. In2, Out3, 1
 4. In2, Out4, 1

我的 table 会小很​​多,但似乎每当我想为某个输入值 X 获取加权随机行时,我需要首先将 Input = X 的所有行提取到内存中然后在代码中做概率测试。

我将每秒进行数千次加权提取,因此速度至关重要。 table 可能包含超过一百万条记录。

该程序是用 C# 编写的,它将使用 SQL 服务器或 MySQL 作为后端,不确定这是否会有很大的不同。

第三种(可能是最快的方法)是采用第二种方法的变体,但使用十进制数字范围,如下所示:

  1. In1, Out1, 0, 0.33
  2. 输入 1,输出 2,0.33,1
  3. 输入 2、输出 3、0、0.5
  4. In2, Out4, 0.5, 1

要 "pick" 一个加权,选择任何输入加上一个介于 0 和 1(不含)之间的随机数,然后在您的 SQL 查询中检查此随机数是否 >= min 和 < max。这可以完美优化并考虑到重量。

您可以使用触发器确保数字在插入时正确分布。