Оптимизация производительности производного подзапроса путем вытягивания отдельных записей в group_concat ()

в этом запросе 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) это те же результаты, что и в первом запросе

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
25
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я бы попробовал:

select x.`id`, 
       (select group_concat(distinct d.`content`)
        from docs
        where docs.`x_id` = 1
       ) as `letters`
from `x`
where x.`id` = 1;

Когда я смотрю на планы выполнения, нормально ли видеть rows: 18, даже когда я получаю отчетливое значение, которое на самом деле составляет 7 из 18 строк? поскольку в таблице может быть почти миллион записей, что даст мне rows: 1000000.

Mark Elvis 19.11.2018 22:55

Еще проще:

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.

Другие вопросы по теме