Obecnie piszę aplikację internetową, która dopasowuje użytkowników do odpowiedzi na pytanie. Zrobiłem mój algorytm dopasowania w jednym zapytaniu i dostroiłem go do tego stopnia, że zajmuje 8.2ms, aby obliczyć procent dopasowania między 2 użytkownikami. Ale moja aplikacja musi pobrać listę użytkowników i przejrzeć listę wykonującą to zapytanie. Dla 5000 użytkowników zajęło 50 sekund na mojej lokalnej maszynie. Czy jest możliwe umieszczenie wszystkiego w jednym zapytaniu, które zwraca jedną kolumnę z identyfikatorem użytkownika i jedną kolumną z wyliczonym dopasowaniem? Czy jest procedura przechowywana opcja?SQL: zwraca tabelę użytkowników z kolumną obliczoną dla procentu dopasowania?
Obecnie pracuję z MySQL, ale w razie potrzeby chcę zmienić bazę danych.
Dla wszystkich zainteresowanych schematu i danych, jakie stworzył SQLFiddle: http://sqlfiddle.com/#!2/84233/1
i moje zapytanie Dopasowanie:
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
Można połączyć podwyrażenie "zwykłe pytania" dwóch "nóg" zapytania. Można również uogólnić podzapytania dla user = 1 i user = 101 na jedno ogólne zapytanie CTE (jeśli DBMS je obsługuje, ale najpierw: Pokaż nam definicje tabel i być może niektóre dane. – wildplasser
Tak, dane z odpowiednim pożądanym wyjściem –
Stworzyłem SQLFiddle do grania :) Kiedy pasuję do użytkownika 1 i 5, wynik powinien wynosić '43 .678 'http://sqlfiddle.com/#!2/84233/1 – Mexxer