現在、回答された質問に基づいてユーザーを照合する webapp を作成しています。たった 1 つのクエリでマッチング アルゴリズムを実現し、2 人のユーザー間の一致率を計算するのに 8.2 ミリ秒かかるように調整しました。しかし、私の webapp はユーザーのリストを取得し、このクエリを実行してリストを反復処理する必要があります。5000 人のユーザーの場合、ローカル マシンで 50 秒かかりました。user_id を含む 1 つの列と計算された一致を含む 1 つの列を返す 1 つのクエリにすべてを入れることは可能ですか? または、ストアド プロシージャはオプションですか?
私は現在 MySQL を使用していますが、必要に応じてデータベースを切り替えます。
スキーマとデータに興味がある人のために、SQLFiddle を作成しました: http://sqlfiddle.com/#!2/84233/1
そして私の一致するクエリ:
SELECT COALESCE(SQRT( (100.0*as1.actual_score/ps1.possible_score) * (100.0*as2.actual_score/ps2.possible_score) ) - (100/ps1.commonquestions), 0) AS perc
FROM (SELECT SUM(imp.value) AS actual_score
FROM user_questions AS uq1
INNER JOIN importances imp ON imp.id = uq1.importance
INNER JOIN user_questions uq2 ON uq2.question_id = uq1.question_id AND uq2.user_id = 101
AND (uq1.accans1 = uq2.answer_id
OR uq1.accans2 = uq2.answer_id
OR uq1.accans3 = uq2.answer_id
OR uq1.accans4 = uq2.answer_id)
WHERE uq1.user_id = 1) AS as1,
(SELECT SUM(value) AS possible_score, COUNT(*) AS commonquestions
FROM user_questions AS uq1
INNER JOIN importances ON importances.id = uq1.importance
INNER JOIN user_questions uq2 ON uq1.question_id = uq2.question_id AND uq2.user_id = 101
WHERE uq1.user_id = 1) AS ps1,
(SELECT SUM(imp.value) AS actual_score
FROM user_questions AS uq1
INNER JOIN importances imp ON imp.id = uq1.importance
INNER JOIN user_questions uq2 ON uq2.question_id = uq1.question_id AND uq2.user_id = 1
AND (uq1.accans1 = uq2.answer_id
OR uq1.accans2 = uq2.answer_id
OR uq1.accans3 = uq2.answer_id
OR uq1.accans4 = uq2.answer_id)
WHERE uq1.user_id = 101) AS as2,
(SELECT SUM(value) AS possible_score
FROM user_questions AS uq1
INNER JOIN importances ON importances.id = uq1.importance
INNER JOIN user_questions uq2 ON uq1.question_id = uq2.question_id AND uq2.user_id = 1
WHERE uq1.user_id = 101) AS ps2