如何使用 MemSQL 获取具有最大点积的行

How to get row with max dot product using MemSQL

首先,我先声明我对 SQL 的经验很少。

无论如何,我在 MemSQL 中有一个 table 格式如下:

+-----+--------+----------+----------+
| id  |  uuid  | identity | template |
+-----+--------+----------+----------+
| int | string | string   | blob     |
+-----+--------+----------+----------+

我正在尝试使用 MemSQL DOT_PRODUCT feature 来获得模板的 identity ,它生成针对我的探测向量的最大点积已提供。笔记模板是固定长度的标准化浮点数组。

我的SQL声明如下:

SELECT id, identity, MAX(DOT_PRODUCT(template, JSON_ARRAY_PACK('[<probe template here>]'))) 
AS score FROM collection;

但是,我似乎遇到了奇怪的行为,我得到的结果不一致(执行查询的 10 次中有 1 次我会得到不同的身份,但总是获得相同的最高分数)。此外,identity 不正确(请参阅下文)。

查询结果如下(10 次中有 9 次):

+----+-------------+------------------+
| id |  identity   |      score       |
+----+-------------+------------------+
|  7 | armstrong_2 | 0.56488848850131 |
+----+-------------+------------------+

作为完整性检查,我编写了以下 SQL 语句,希望最大值相同。请注意,我使用的是与之前完全相同的探针向量:

SELECT id, identity, DOT_PRODUCT(template, JSON_ARRAY_PACK('[<same probe template from before>]')) 
AS score FROM collection ORDER BY score DESC;

结果如下:

+----+--------------+--------------------+
| id |   identity   |       score        |
+----+--------------+--------------------+
|  1 | armstrong_1  | 0.56488848850131   |
| 21 | armstrong_1  | 0.56488848850131   |
|  6 | armstrong_1  | 0.56488848850131   |
| 11 | armstrong_1  | 0.56488848850131   |
| 16 | armstrong_1  | 0.56488848850131   |
| 17 | armstrong_2  | 0.534708674997091  |
|  7 | armstrong_2  | 0.534708674997091  |
| 22 | armstrong_2  | 0.534708674997091  |
|  2 | armstrong_2  | 0.534708674997091  |
| 12 | armstrong_2  | 0.534708674997091  |
| 10 | mr_bean_2    | 0.072085081599653  |
| 15 | mr_bean_2    | 0.072085081599653  |
|  5 | mr_bean_2    | 0.072085081599653  |
| 20 | mr_bean_2    | 0.072085081599653  |
| 25 | mr_bean_2    | 0.072085081599653  |
| 14 | mr_bean      | 0.037121964152902  |
|  9 | mr_bean      | 0.037121964152902  |
|  4 | mr_bean      | 0.037121964152902  |
| 19 | mr_bean      | 0.037121964152902  |
| 24 | mr_bean      | 0.037121964152902  |
| 13 | jimmy_carter | -0.011749440804124 |
| 23 | jimmy_carter | -0.011749440804124 |
| 18 | jimmy_carter | -0.011749440804124 |
|  8 | jimmy_carter | -0.011749440804124 |
|  3 | jimmy_carter | -0.011749440804124 |
+----+--------------+--------------------+

这是怎么回事?为什么第一个查询的 MAX 身份与第二个查询的最大身份(第一行)不同?我的一个/两个查询语句不正确吗?

此外,当我手动计算点积时(没有任何 SQL 或 MemSQL),我发现 armstrong_1 确实产生了最高分 0.56488848850131.那么,为什么我的第一个 SQL 查询(使用 MAX 运算符)不起作用?

这根本无效SQL:

SELECT id, identity, MAX(DOT_PRODUCT(template, JSON_ARRAY_PACK('[<probe template here>]'))) AS score
FROM collection;

你没有 GROUP BY 但查询是一个聚合函数(由于 MAX()。然后还有另外两个列。这无效 SQL 很遗憾一些数据库允许它。

最好的方法是ORDER BY:

SELECT id, identity, DOT_PRODUCT(template, JSON_ARRAY_PACK('[<probe template here>]')) AS score
FROM collection
ORDER BY score DESC
LIMIT 1;   -- or whatever your database uses to limit to one row