#mysql #performance #join #coalesce #explain
#mysql #Производительность #Присоединиться #объединить #объясните
Вопрос:
У меня есть запрос с планом объяснения ниже. Он довольно простой, каждое объединение использует индекс (хотя и не уникальный), и это занимает более 5 часов. Самая большая таблица содержит около 100 тыс. записей. Оперативная память и процессор не привязаны или что-то еще, никаких других запущенных запросов, никаких блокировок таблиц. Самая «сложная» часть, которая у меня есть, — это объединение во внешнем соединении. Это меня убивает?
Для пояснения я присоединяюсь к одной и той же таблице дважды, потому что некоторые записи имеют идентификатор пользователя, у некоторых есть только имя / фамилия. Я предпочитаю объединяться с помощью уникального имени пользователя, очевидно, и один из выбранных элементов — coalesce (u1.job_title, u2.job_title)
from utilization_incident ui
left join users_utilization_v u1
on u1.cc_user_id = ui.assigned_to_user_id
and u1.source_system = ui.source
and u1.data_date = ui.data_date
left join users_utilization_v u2
on u2.first_name = ui.assigned_to_first_name
and u2.last_name = ui.assigned_to_last_name
and u2.source_system = ui.source
and u2.data_date = ui.data_date
left join lkp_job_title_service_area jtsa
on jtsa.job_title = coalesce(u1.job_title, u2.job_title)
Комментарии:
1. просто: попробуйте запустить SQL без
coalesce
и посмотрите, заметно ли это быстрее2. Без более глубокого понимания того, как соотносятся данные (и какие точные индексы доступны), трудно дать много советов; но … да, это объединение в качестве условия объединения, вероятно, не приносит вам никакой пользы; вероятно, это приводит к полному сканированию обеих задействованных таблиц. Вероятно, вам лучше использовать два отдельных соединения с этой таблицей (одно с u1, а другое с u2) и решить, какие значения joined
jtsa
использовать в списке выбора.3. Кроме того, не все так ясно, что вам нужно присоединиться к
users_utilization_v
дважды, когда вы могли бы просто объединить условия объединения.OR
s редко бывают оптимальными в условиях объединения, но и ненужными объединения не являются.4.
LEFT
собирает недостающие строки — вы действительно этого хотите?
Ответ №1:
Возможно, процессор не привязан, но как насчет ввода-вывода?
Сколько оперативной памяти? Какова ценность innodb_buffer_pool_size
?
Пожалуйста, предоставьте SHOW CREATE TABLE
.
Пожалуйста, предоставьте весь SELECT
.
Пожалуйста, предоставьте текстовую версию EXPLAIN SELECT ...
.
В ожидании дальнейших подробностей эти индексы должны помочь:
users_utilization_v: INDEX(cc_user_id, source_system, data_date)
users_utilization_v: INDEX(first_name, last_name, source_system, data_date)
lkp_job_title_service_area: INDEX(job_title)
Удалите LEFT
, если вам это не нужно.