Проблема
Учитывая запрос пользователя Q
на веб-странице, я пытаюсь вычислить следующую несколько сложную функцию для каждой сущности p
в моей базе данных:
(D
также зависит от пользовательского запроса Q
) В моей базе данных примерно 440 000 p
сущностей, каждая из которых имеет в среднем ~ 50 связанных w_{d,p}
веса и ~ 400 связанных u_{p, c}
весов. Прямо сейчас эти веса хранятся в трех таблицах, и есть дополнительная таблица, которая определяет отношения между d
и c
:
table columns indices
----- ------- ----
w weights: p | d | w_pd primary key (p, d), index on d
u weights: p | c | u_pc primary key (p, c), index on c
v weights: c | v_c primary key c
d/c relationship: d | c primary key (d, c), index on c
Идентификаторы p
, d
и c
- все варианты, размер которых варьируется от 10 до 16. w_dp
, u_pc
и v_c
являются числами с плавающей точкой.
Мой нынешний подход к вычислению вышеприведенного уравнения предусматривает несколько объединений, подзапросов, операторов по группам и т. Д. В зависимости от Q
мы можемиметь возможность обрезать набор интересующих нас p
сущностей до более управляемого числа, и вычисление может занять всего несколько секунд. Но некоторые значения Q
приводят к вычислению, которое занимает несколько минут.
Пример вычисления
Предположим, у нас есть следующие четыре таблицы:
d/c relationship w weights u weights v weights
d | c p | d | w_dp p | c | u_pc c | v_c
d1 | c1 p1 | d1 | 1 p1 | c1 | 6 c1 | 12
d1 | c2 p1 | d2 | 3 p1 | c2 | 8 c2 | 16
d2 | c2 p2 | d1 | 2 p2 | c1 | 11 c3 | 15
d3 | c3 p3 | d2 | 4 p3 | c2 | 7
p3 | d3 | 5 p3 | c3 | 9
p4 | d3 | 10 p4 | c1 | 13
Запрос *На самом деле 1040 * - это набор c
идентификаторов, который ограничивает набор D
, в котором сумма окончена. Итак, скажем Q = {c1, c2}
. Используя таблицу отношений d / c, наша сумма будет больше d1
и d2
. Вычисляя сумму для p1
, мы имеем:
d1: 1 * max(6, 8) * [v_c : c = argmax_c (u_11=6, u_12=8)] = 1 * 8 * 16 = 128
d2: 3 * max(8) * [v_c : c = argmax_c (u_12=8)] = 3 * 8 * 16 = 384
Таким образом, оценка для p1
составляет 128 + 384 = 512. Мы сделали бы аналогичные вычисления для p2
и p3
. p4
связан только с d3
, а d3
не имеет отношения к Q = {c1, c2}
, поэтому нам нечем суммировать p4
.
Вопрос
Есть лиразумный способ быстро вычислить вышеуказанную функцию? В частности,
Используете существующую схему БД? Насколько я понимаю, использование агрегатных функций над объединенными таблицами, как я сейчас делаю, довольно медленное, поэтому я предполагаю, что ответом на этот вопрос будет «нет».
Использование альтернативной таблицыструктура? Моя единственная текущая идея - объединить веса w / u / v в одну массивную таблицу строк длиной ~ 700 м и использовать эту таблицу для запроса. Я не уверен, насколько это будет полезно, но, может быть, правильная индексация может быть быстрее.
Должен ли я сделать что-то еще полностью? Есть ли альтернативный инструмент для хранения / обработки данных, который я должен рассмотреть?
Поскольку я очень начинающий, когда дело доходит до SQL, я надеялся получить более четкое представление о направлении, прежде чемЯ трачу слишком много времени на тупик.
Обновление
Я знаю, что это не получило большой тяги, но для будущих зрителей: способ, которым я решил это, был, делая все вычисления передвремя. Существует около 5000 возможных запросов q
и максимум ~ 500 000 объектов p
. В результате получится таблица размером 2,5 миллиарда строк, где (p, q)
- это первичный ключ. В действительности, для каждого запроса q в среднем присваивается только примерно 75 000 объектов, что приводит к чуть более управляемому размеру таблицы 75000 * 5000 = 375 000 000. Теперь, во время запроса, все, что мне нужно сделать, чтобы получить соответствующий список оценок, это фильтр на q
, что намного проще, чем делать это сумасшедшее суммирование.
Тем не менее, если кто-то увидит это и внесет свой вклад, я все равно хотел бы услышать мнение любых экспертов по SQL / MySQL.