Очень медленный запрос с MySQL (& quot; Отправка данных & quot;)

В настоящее время я разрабатываю приложение PHP / MySQL с использованием инфраструктуры CodeIgniter.

У меня довольно длинный запрос, который вызывает несколько проблем. Проблема возникает при изменении диапазона дат на более длительный период, скажем, 30 дней, в отличие от значения по умолчанию, которое составляет 7 дней. Время запроса значительно увеличивается: от 1/2 до 90 секунд, но я могу только предположить, что это из-за увеличения размера данных.

Прежде чем я вставлю запрос, приведу краткое объяснение таблиц:

  • flagged_cases: список уникальных случаев (основная таблица) — 352 строки
  • источники данных: список источников данных, каждый случай ссылается на эту таблицу с помощью внешнего ключа — 20 строк
  • Матчи: строки текста соответствуют случаю (отношение один ко многим, т.е. один случай, много совпадений) — 22000 строк
  • flagged_cases_keywords_hits: сопоставление идентификаторов наблюдений с ключевыми словами (и количеством обращений) — 2500 строк
  • ключевые слова: список ключевых слов — 121 ряд
  • reviewed_state: идентификатор / описание для 3 состояний, только когда-либо проверяя Review_state = 1 для этого запроса — 3 строки

Ниже приведен запрос, я понимаю, что он довольно большой, но я думаю, что с индексами должна быть основная проблема, к сожалению, у меня просто нет знаний, чтобы полностью устранить неполадки, поэтому любая помощь приветствуется.

SELECT    flagged_cases.id,
data_source_id,
title,
fetch_date,
publish_date,
case_id,
case_title,
case_link,
relevance_score,
(
SELECT   group_concat(match_string_highlighted ORDER BY matches.id SEPARATOR "")
FROM     matches
WHERE    flagged_case_id=flagged_cases.id) AS all_matches,
reviewed_state_id,
(
SELECT   group_concat(concat(k.keyword, " ", "x", cast(kh.hits AS CHAR), "") SEPARATOR "")
FROM     flagged_cases_keywords_hits kh
JOIN     keywords k
ON       kh.keyword_id = k.id
WHERE    kh.flagged_case_id = flagged_cases.id
ORDER BY k.weighting DESC) AS hitcount
FROM      flagged_cases
JOIN      data_sources
ON        flagged_cases.data_source_id = data_sources.id
JOIN      reviewed_state
ON        flagged_cases.reviewed_state_id = reviewed_state.id
LEFT JOIN matches
ON        flagged_cases.id = matches.flagged_case_id
WHERE     reviewed_state_id = 1
AND       data_source_id IN('1',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20')
AND       fetch_date >= '2015-05-10 00:00:00'
AND       fetch_date <= '2015-05-17 23:59:59'
GROUP BY  flagged_cases.id
ORDER BY  title DESC
LIMIT     10;

В результате выполнения SHOW FULL PROCESSLIST я вижу, что запрос остается в состоянии «Отправка данных», которое, как я вижу из некоторых исследований, в основном происходит выборка и выборка данных MySQL, поэтому я могу только предположить, что должен быть отсутствующий индекс или что-то, вызывающее это. замедлить.

Я также получил ОБЪЯСНЕНИЕ запроса, который выглядит следующим образом:

+----+--------------------+----------------+--------+----------------------------------+-----------------+---------+----------------------------+------+----------------------------------------------+
| id | select_type        | table          | type   | possible_keys                    | key             | key_len | ref                        | rows | Extra                                        |
+----+--------------------+----------------+--------+----------------------------------+-----------------+---------+----------------------------+------+----------------------------------------------+
|  1 | PRIMARY            | reviewed_state | const  | PRIMARY                          | PRIMARY         | 4       | const                      |    1 | Using index; Using temporary; Using filesort |
|  1 | PRIMARY            | data_sources   | range  | PRIMARY                          | PRIMARY         | 4       | NULL                       |   19 | Using where                                  |
|  1 | PRIMARY            | flagged_cases  | ref    | data_source_id,reviewed_state_id | data_source_id  | 4       | proactive.data_sources.id  |   14 | Using where                                  |
|  1 | PRIMARY            | matches        | ref    | flagged_case_id                  | flagged_case_id | 4       | proactive.flagged_cases.id |   32 | Using index                                  |
|  3 | DEPENDENT SUBQUERY | kh             | ref    | flagged_case_id,keyword_id       | flagged_case_id | 5       | func                       |    3 | Using where; Using temporary                 |
|  3 | DEPENDENT SUBQUERY | k              | eq_ref | PRIMARY                          | PRIMARY         | 4       | proactive.kh.keyword_id    |    1 | Using where                                  |
|  2 | DEPENDENT SUBQUERY | matches        | ref    | flagged_case_id                  | flagged_case_id | 4       | func                       |   32 |                                              |
+----+--------------------+----------------+--------+----------------------------------+-----------------+---------+----------------------------+------+----------------------------------------------+

Любая помощь / совет / советы очень ценятся! 🙂

2

Решение

Можете ли вы попробовать это, чтобы увидеть, приносит ли это какую-либо выгоду?

Подзапросы в вашем списке выбора заменяются встроенными представлениями, которые группируются по значениям, которые объединяются с вашими другими таблицами.

select      flagged_cases.id,
data_source_id,
title,
fetch_date,
publish_date,
case_id,
case_title,
case_link,
relevance_score,
v1.all_matches,
reviewed_state_id,
v2.hitcount
from        flagged_cases
join data_sources
on flagged_cases.data_source_id = data_sources.id
join reviewed_state
on flagged_cases.reviewed_state_id = reviewed_state.id
join (
select      group_concat(match_string_highlighted order by matches.id separator "") as all_matches
from        matches
group by    flagged_case_id
) v1
on v1.flagged_case_id = flagged_cases.id
join (
select      group_concat(concat(k.keyword, " ", "x", cast(kh.hits as char), "") order by k.weighting desc separator "")
from        flagged_cases_keywords_hits kh
join keywords k
on kh.keyword_id = k.id
group by    kh.flagged_case_id
) v2
on v2.flagged_case_id = flagged_cases.id
left join matches
on flagged_cases.id = matches.flagged_case_id
where       reviewed_state_id = 1
and data_source_id in('1','3','4','5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20')
and fetch_date >= '2015-05-10 00:00:00'
and fetch_date <= '2015-05-17 23:59:59'
group by    flagged_cases.id
order by    title desc
limit       10;
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]