оптимизация производительности производных подзапросов, извлекающих отдельные записи в group_concat () - PullRequest
0 голосов
/ 19 ноября 2018

в этом запросе 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, поэтому я хотел их четко вытащить, чтобы я пошел по пути скалярного запроса но может ли запрос стать более оптимизированным?

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

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Еще проще:

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.

0 голосов
/ 19 ноября 2018

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

select x.`id`, 
       (select group_concat(distinct d.`content`)
        from docs
        where docs.`x_id` = 1
       ) as `letters`
from `x`
where x.`id` = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...