如何从 "float" 迁移到 MySQL 中的 "points"?
How can I migrate from "float" to "points" in MySQL?
我正在寻找一种更快的方法来计算 SQL 中的欧几里得距离。
- 我想解决的问题
下面的“欧式距离计算”比较慢
SELECT
id,
sqrt(
power(f1 - (-0.09077361), 2) +
power(f2 - (0.10373443), 2) +
...
...
power(f127 - (0.0778369), 2) +
power(f128 - (0.00951046), 2)
) as distance
FROM
face_feature
ORDER BY
distance
LIMIT
1
;
- 我想知道的
能否分享一下如何从“浮点数”迁移到“点数”?
我收到了以下建议,但我不明白是怎么回事。
Switch to POINTs and a SPATIAL index. It may be possible your task orders of magnitude faster.
- MySQL
mysql> SHOW VARIABLES LIKE '%version%';
+--------------------------+------------------------------+
| Variable_name | Value |
+--------------------------+------------------------------+
| version | 8.0.29 |
| version_comment | MySQL Community Server - GPL |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+--------------------------+------------------------------+
- Table
mysql> desc face_feature;
+-------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| f1 | float(9,8) | NO | | NULL | |
| f2 | float(9,8) | NO | | NULL | |
..
| f127 | float(9,8) | NO | | NULL | |
| f128 | float(9,8) | NO | | NULL | |
+-------+------------+------+-----+---------+----------------+
- 数据
mysql> SELECT count(*) FROM face_feature;
+----------+
| count(*) |
+----------+
| 100003 |
+----------+
mysql> SELECT * FROM face_feature LIMIT 1\G;
id: 1
f1: -0.07603023
f2: 0.13605964
...
f127: 0.09608927
f128: 0.00082345
- 参考(我的另一个问题)
不要使用 FLOAT(M,N)
它会添加额外的舍入,这只会损害各种操作。
FLOAT(9,8)
,如果数字接近“1.0”,将失去一些精度。这是因为任何 FLOAT
.
中只有 24 位精度
(m,n)
FLOAT
和 DOUBLE
在 MySQL.[=22= 的较新版本中已被弃用(因为无用且具有误导性) ]
有辅助函数可以将数字字符串转换为 POINT
值。在内部,一个 POINT
包含两个 DOUBLEs
。因此,原来的 DECIMAL(9,8)
在第 53 个有效位只丢失了一个 round-from-decimal-to-binary。
但真正的问题是关于在宇宙有 128 个维度时使用 SPATIAL
索引。我不认为它会工作。 (我什至没有听说过对 3 维使用 SPATIAL
,尽管它应该很实用。)
我正在寻找一种更快的方法来计算 SQL 中的欧几里得距离。
- 我想解决的问题
下面的“欧式距离计算”比较慢
SELECT
id,
sqrt(
power(f1 - (-0.09077361), 2) +
power(f2 - (0.10373443), 2) +
...
...
power(f127 - (0.0778369), 2) +
power(f128 - (0.00951046), 2)
) as distance
FROM
face_feature
ORDER BY
distance
LIMIT
1
;
- 我想知道的
能否分享一下如何从“浮点数”迁移到“点数”?
我收到了以下建议,但我不明白是怎么回事。
Switch to POINTs and a SPATIAL index. It may be possible your task orders of magnitude faster.
- MySQL
mysql> SHOW VARIABLES LIKE '%version%';
+--------------------------+------------------------------+
| Variable_name | Value |
+--------------------------+------------------------------+
| version | 8.0.29 |
| version_comment | MySQL Community Server - GPL |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+--------------------------+------------------------------+
- Table
mysql> desc face_feature;
+-------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| f1 | float(9,8) | NO | | NULL | |
| f2 | float(9,8) | NO | | NULL | |
..
| f127 | float(9,8) | NO | | NULL | |
| f128 | float(9,8) | NO | | NULL | |
+-------+------------+------+-----+---------+----------------+
- 数据
mysql> SELECT count(*) FROM face_feature;
+----------+
| count(*) |
+----------+
| 100003 |
+----------+
mysql> SELECT * FROM face_feature LIMIT 1\G;
id: 1
f1: -0.07603023
f2: 0.13605964
...
f127: 0.09608927
f128: 0.00082345
- 参考(我的另一个问题)
不要使用
FLOAT(M,N)
它会添加额外的舍入,这只会损害各种操作。
中只有 24 位精度FLOAT(9,8)
,如果数字接近“1.0”,将失去一些精度。这是因为任何FLOAT
.(m,n)
FLOAT
和DOUBLE
在 MySQL.[=22= 的较新版本中已被弃用(因为无用且具有误导性) ]有辅助函数可以将数字字符串转换为
POINT
值。在内部,一个POINT
包含两个DOUBLEs
。因此,原来的DECIMAL(9,8)
在第 53 个有效位只丢失了一个 round-from-decimal-to-binary。
但真正的问题是关于在宇宙有 128 个维度时使用 SPATIAL
索引。我不认为它会工作。 (我什至没有听说过对 3 维使用 SPATIAL
,尽管它应该很实用。)