画像に関するデータを保存する次の表があります。
images
- id (int)
- sample_1_1 (int)
- sample_1_2 (int)
- sample_1_3 (int)
- sample_2_1 (int)
- sample_2_2 (int)
- sample_2_3 (int)
- ... # Up until sample_25_3
タスクは、収集されたデータ間の距離を計算することです。現在、データベースにストアドプロシージャとしてプログラムされた75次元(そうです、3 * 25 = 75)のユークリッド距離計算を使用しています。
CREATE DEFINER=`root`@`localhost`
FUNCTION `distanceBetween`(compareId INT, toId INT) RETURNS double
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE distance DOUBLE;
SELECT euclidDistance(
i1.sample_1_1, i1.sample_1_2, i1.sample_1_3,
i2.sample_1_1, i2.sample_1_2, i2.sample_1_3,
...
) INTO distance
FROM images i1, (SELECT * FROM images WHERE id = toId) i2
WHERE i1.id = compareId;
RETURN distance;
END
別のサブルーチンを使用して、275-dim間の実際の距離を計算します。ベクトル:
CREATE DEFINER=`root`@`localhost`
FUNCTION `euclidDistance`(
img1_sample1_1 INT, img1_sample1_2 INT, img1_sample1_3 INT,
img2_sample1_1 INT, img2_sample1_2 INT, img2_sample1_3 INT,
...
) RETURNS double
RETURN SQRT(
quadDiff(img1_sample1_1, img2_sample1_1)
+ quadDiff(img1_sample1_2, img2_sample1_2)
+ quadDiff(img1_sample1_3, img2_sample1_3)
+ ...
)
そして、2つの値の差の2乗を計算する別のサブルーチン:
CREATE DEFINER=`root`@`localhost`
FUNCTION `quadDiff`(var1 INT, var2 INT) RETURNS int(11)
RETURN POW(var1 - var2, 2)
関数自体は完全に細かく、数学的にも論理的にも正しい決定論的な結果を返します。
問題は、特定の画像に「最も近い」画像、つまり特定の画像までの距離が最も短い画像を取得したい場合に発生します。そうするために、私は別の手順を使用します:
CREATE DEFINER=`root`@`localhost`
PROCEDURE `getSimilarImages`(imageId INT, `limit` INT)
BEGIN
SELECT i2.id, i2.filename, distanceBetween(i1.id, i2.id) distance
FROM images i1, (SELECT * FROM images WHERE id != imageId AND duplicateImageId IS NULL) i2
WHERE i1.id = imageId
ORDER BY distance
LIMIT 10;
END
データベースには現在、約30.000枚の画像が含まれています。これは、aが終了するのCALL getSimilarImages(123, 10);
に約12秒かかることを意味します。これは、Webベースであろうとアプリケーションベースであろうと、どのアプリケーションにとっても長すぎます。
だから、私は物事をスピードアップしたいと思います。私のオプションは何ですか?距離を比較または計算する画像のプロセスを最適化する可能性はありますか?
手順の結果をキャッシュすることを考えましたが、その方法がわかりません。新しい画像が追加されるとすぐに、すべての画像を他のすべての画像と比較することもできますが、それでは画像が非常に長いプロセスで追加されるため、これも受け入れられません。
役立つ場合は、システムセットアップに関する詳細情報を提供できますが、ご提供いただけるアドバイスをいただければ幸いです。現在の状況は良くなく、私は本当に何かをする必要があります。なぜなら、イメージデータベースはシステムが稼働する時間ごとにしか大きくならないからです。