У меня очень медленный (обычно около 60 секунд) запрос MySQL, который пытается найти корреляции между тем, как пользователи голосовали в одном опросе, и тем, как они голосовали во всех предыдущих опросах.
По сути, мы собираем идентификаторы всех, кто голосовал за один конкретный вариант в данном опросе.
Затем мы видим, как эта подгруппа голосовала в каждом предыдущем опросе, и сравниваем эти результаты с тем, как ВСЕ (а не только подгруппа) голосовали в этом опросе. Разница между результатами подгруппы и общими результатами является отклонением, и этот запрос сортируется по отклонению для определения наиболее сильной корреляции.
Запрос вроде беспорядка:
(SELECT p_id as poll_id, o_id AS option_id, description, optCount AS option_count, subgroup_percent, total_percent, ABS(total_percent - subgroup_percent) AS deviation
FROM(
SELECT poll_id AS p_id,
option_id AS o_id,
(SELECT description FROM `option` WHERE id = o_id) AS description,
COUNT(*) AS optCount,
(SELECT COUNT(*) FROM response INNER JOIN user_ids_122 ON response.user_id = user_ids_122.user_id WHERE option_id = o_id ) /
(SELECT COUNT(*) FROM response INNER JOIN user_ids_122 ON response.user_id = user_ids_122.user_id WHERE poll_id = p_id) AS subgroup_percent,
(SELECT COUNT(*) FROM response WHERE option_id = o_id) /
(SELECT COUNT(*) FROM response WHERE poll_id = p_id) AS total_percent
FROM response
INNER JOIN user_ids_122 ON response.user_id = user_ids_122.user_id
WHERE poll_id < '61'
GROUP BY option_id DESC
) AS derived_table_122
)
ORDER BY deviation DESC, option_count DESC
Обратите внимание, что user_ids_122 - это ранее созданная временная таблица, содержащая идентификаторы всех пользователей, проголосовавших за идентификатор опции 122.
В таблице «response» содержится около 65 000 строк, в таблице «user» - около 7 000 строк, а в таблице «option» - около 130 строк.
UPDATE
Вот таблица EXPLAIN ...
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 121 Using filesort
2 DERIVED user_ids_122 ALL NULL NULL NULL NULL 74 Using temporary; Using filesort
2 DERIVED response ref poll_id,user_id user_id 4 correlated.user_ids_122.user_id 780 Using where
7 DEPENDENT SUBQUERY response ref poll_id poll_id 4 func 7800 Using index
6 DEPENDENT SUBQUERY response ref option_id option_id 4 func 7800 Using index
5 DEPENDENT SUBQUERY user_ids_122 ALL NULL NULL NULL NULL 74
5 DEPENDENT SUBQUERY response ref poll_id,user_id poll_id 4 func 7800 Using where
4 DEPENDENT SUBQUERY user_ids_122 ALL NULL NULL NULL NULL 74
4 DEPENDENT SUBQUERY response ref user_id,option_id user_id 4 correlated.user_ids_122.user_id 780 Using where
3 DEPENDENT SUBQUERY option eq_ref PRIMARY PRIMARY 4 func 1
ОБНОВЛЕНИЕ 2:
Каждая строка в таблице «response» выглядит следующим образом:
id (INT) poll_id (INT) user_id (INT) option_id (INT) created (DATETIME)
7 7 1 14 2011-03-17 09:25:10
Каждая строка в таблице «option» выглядит следующим образом:
id (INT) poll_id (INT) text (TEXT) description (TEXT)
14 7 No people who dislike country music
Каждая строка в таблице «user» выглядит следующим образом:
id (INT) email (TEXT) created (DATETIME)
1 user@example.com 2011-02-15 11:16:03