в этом запросе https://www.db-fiddle.com/f/wi525XMRAff2GHUrBpWAM8/5
select x.`id`, (
select
group_concat(d.`content`)
from (
select
docs.`content`
from
`docs`
where
docs.`x_id` = 1
group by
docs.`content`
) as `d`
) as `letters`
from `x`
where x.`id` = 1;
Я должен был вытащить x.id из x table и с ним буквы из docs table, связанные с помощью docs.x_id один раз, и поэтому я использовал статический x.id = 1
буквы в docs table могут быть дублированы для одного и того же x_id, поэтому я хотел вытащить его отчетливо, поэтому я пошел по маршруту скалярный запрос, но может ли запрос стать более оптимизированным?
Я использую последнюю версию Мариадб и дает мне extra: Using index; Using temporary; Using filesort в отличие от того, что в скрипке показывает extra: Using index condition; Using temporary
я также пробовал использовать этот запрос https://www.db-fiddle.com/f/wi525XMRAff2GHUrBpWAM8/4
select x.`id`, group_concat(d.`content`) as `letters`
from `x`
inner join (
select
d.`x_id`, d.`content`
from
`docs` d
where
d.`x_id` = 1
group by
d.`x_id`, d.`content`
) d ON d.`x_id` = 1
where x.`id` = 1;
что дает лучшие результаты плана выполнения для MySQL 8, но на mariadb (MySQL 5.5.5) это те же результаты, что и в первом запросе


Я бы попробовал:
select x.`id`,
(select group_concat(distinct d.`content`)
from docs
where docs.`x_id` = 1
) as `letters`
from `x`
where x.`id` = 1;
Еще проще:
SELECT 1 AS id,
GROUP_CONCAT(DISTINCT content) AS letters
FROM docs
WHERE x_id = 1
Однако я подозреваю, что вы слишком упростили запрос. Так что это упрощение не может применяться полностью.
В любом случае старайтесь не думать о «подзапросе» как о решении проблем. Обратите внимание, что вам понадобилось 2 подзапроса, но я сделал это в 0. И, вероятно, это намного быстрее.
Для дальнейшего ускорения замените INDEX(x_id) на INDEX(x_id, content).
«Использование файловой сортировки» и «Использование временного» - это конец света для нет. В некоторых запросах они абсолютно необходимы. Кроме того, «сортировка файлов» обычно выполняется в ОЗУ; при съемке этого запроса ни один диск не поврежден. Думаю, мой запрос иINDEX все равно их избегает.
Внимание! Для GROUP_CONCAT существует ограничение дефолт, равное 1024. См. group_concat_max_len.
Когда я смотрю на планы выполнения, нормально ли видеть
rows: 18, даже когда я получаю отчетливое значение, которое на самом деле составляет 7 из 18 строк? поскольку в таблице может быть почти миллион записей, что даст мнеrows: 1000000.