我正在創建一個人臉識別系統,但搜索速度很慢。你能分享一下如何加快搜索速度嗎?
100,000 個資料項大約需要 6 秒。
- 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 |
-------------------------- ------------------------------
- 桌子
CREATE TABLE `face_feature` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`f1` decimal(9,8) NOT NULL,
`f2` decimal(9,8) NOT NULL,
...
...
`f127` decimal(9,8) NOT NULL,
`f128` decimal(9,8) NOT NULL,
PRIMARY KEY (id)
);
- 資料
mysql> SELECT count(*) FROM face_feature;
----------
| count(*) |
----------
| 110004 |
----------
mysql> SELECT * FROM face_feature LIMIT 1\G;
id: 1
f1: -0.07603023
f2: 0.13605964
...
f127: 0.09608927
f128: 0.00082345
- 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
;
- 結果
---- --------------------
| id | distance |
---- --------------------
| 1 | 0.3376853491771237 |
---- --------------------
1 row in set (6.18 sec)
更新1:
從更改decimal(9,8)為float(9,8)
然后,從改進approximately 4sec到3.26 sec
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 | |
------- ------------ ------ ----- --------- ----------------
更新 2:
從更改POWER(z, 2)為z*z
然后,結果從更改3.26 sec為4.65 sec
SELECT
id,
sqrt(
((f1 - (-0.09077361)) * (f1 - (-0.09077361)))
((f2 - (0.10373443)) * (f2 - (0.10373443)))
((f3 - (0.00798536)) * (f3 - (0.00798536)))
...
...
((f126 - (0.07803915)) * (f126 - (0.07803915)))
((f127 - (0.0778369)) * (f127 - (0.0778369)))
((f128 - (0.00951046)) * (f128 - (0.00951046))
) as distance
FROM
face_feature
ORDER BY
distance
LIMIT
1
;
更新 3
我正在研究 MySQL GIS 的使用。
如何在 MySQL 中從“float”遷移到“points”?
更新 4
我也在研究 PostgreSQL,因為我找不到在 MySQL 中處理 128 維的方法。
uj5u.com熱心網友回復:
DECIMAL(9,8)- 這是很多有效數字。你需要那么精確嗎?FLOAT-- 約 7 位有效數字;更快的算術。POWER(z, 2)- 可能比z*z. (這可能是最慢的部分。)SQRT-- 在許多情況下,您可以簡單地使用正方形。在這種情況下:SELECT SQRT(closest) FROM ( SELECT -- leave out SQRT ... ORDER BY .. LIMIT 1 )
這里有一些其他的想法。它們不一定與正在討論的查詢相關:
精確測驗——當心比較“相等”的舍入錯誤可能會意外地使事情變得不相等。不精確的測量增加了這個問題。如果我測量兩次,我可能一次得到 1.23456789,下一次得到 1.23456788。(特別是在那個“精度”級別。
交易復雜性與速度——
ABS(a - b)用作距離公式;以這種方式找到最接近的 10 個專案,然后使用歐幾里德距離來獲得“正確”的距離。將面分成多個區域。找出專案所在的區域,然后僅檢查該區域中 128 個點的子集。(靠近邊界——在兩個區域中放置一些點。)
開箱即用——我不熟悉你的面部識別,所以我已經用完了數學技巧。
切換到
POINTs和一個SPATIAL索引。您的任務可能會更快幾個數量級。(這對于 128 維空間可能不實用。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/468620.html
上一篇:Laravel查詢:orderBy不與groupBy一起使用(帶有連接表)
下一篇:如何在Java、JDK17、“module-info.java”、Netbeans、Maven上“要求”模塊“gwt.user”
