Внутреннее соединение SQL - улучшение производительности - PullRequest
0 голосов
/ 11 июня 2018

У меня есть следующий SQL, но я хочу улучшить производительность (вариант 2, приведенный ниже, в настоящее время занимает около 24 секунд).

ОБЪЯСНИТЬ MySQL - используя приведенный ниже пример ответа enter image description here

Вариант 1 - базовый выбор (очень медленный)

select f.name, f.flowid, m.traceid, m.traceday, m.logtimestamp
from flow f, messageinfo m 
where traceid = (select max(traceid) from messageinfo where flowid = f.flowid)

ОБНОВЛЕНИЕ

Вариант 2 - с внутренним соединением (быстрее, но все еще слишком медленно)

select m.traceid, f.name, f.flowid, m.traceday, m.logtimestamp
from flow f
  inner join messageinfo m 
  on m.flowid = f.flowid
  where traceid = (select max(traceid) from messageinfo where flowid = 
  f.flowid)
order by f.name

Мне нужно перебрать записи потока (их около 900) и для каждого потока выбрать связанный поток в messageinfoтаблица, которая является самой последней, то есть имеет самый высокий traceid для этого конкретного потока.Оба приведенных выше примера SQL работают, но хотелось бы посмотреть, смогу ли я повысить производительность для варианта 2, если это возможно.Окончательный результат должен быть наилучшим и должен возвращать трассировку только там, где может быть найдена соответствующая запись потока (например, внутреннее соединение).Кто-нибудь может предложить более эффективный способ?Имейте в виду, что я хотел бы вернуть данные из обеих таблиц в конечном результате (как показано в примере выше).

Я также должен подчеркнуть, что у меня нет свободы изменять DB с помощью новой /обновленные индексы.Так что в основном ищем улучшения SQL без модификаций БД.

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

Ответы [ 5 ]

0 голосов
/ 11 июня 2018

Почему бы не использовать оконную функцию, такую ​​как: max (traceid) over (разделение по порядку трассировки по traceid) из сообщения info

?

0 голосов
/ 11 июня 2018

Ваш запрос в порядке - хотя вы должны написать его, используя полные имена столбцов для всех столбцов :

select m.traceid, f.name, f.flowid, m.traceday, m.logtimestamp
from flow f inner join
     messageinfo m 
     on m.flowid = f.flowid
where m.traceid = (select max(m2.traceid) from messageinfo m2 where m2.flowid = m.flowid)
order by f.name;

Вам нужны индексы для messageinfo(flowid, traceid).Индекс на flow(name, flowid) также может помочь.

0 голосов
/ 11 июня 2018

Другой способ переписать ваш запрос, используя соединение, переместите свою зависимую часть подзапроса в подраздел sub и присоедините его к основному запросу.

select m.traceid, f.name, f.flowid, m.traceday, m.logtimestamp
from flow f
inner join messageinfo m on m.flowid = f.flowid
inner join (
    select flowid, max(traceid) traceid
    from messageinfo 
    group by flowid
) m1 on  m.flowid = m1.flowid and m.traceid = m1.traceid
order by f.name

Также добавьте составной индекс (flowid, traceid)

0 голосов
/ 11 июня 2018

Так же как и инструкции SHOW CREATE TABLE для всех соответствующих таблиц, вопросы о производительности запросов всегда ОБЪЯСНЯЮТ для данного запроса.

Тем не менее, и, пока я ожидаю появления необходимой информации, по моему опытунекоррелированный подзапрос может иногда опережать коррелированный, поэтому я хотел бы попытаться написать запрос следующим образом:

select m.traceid
     , f.name
     , f.flowid
     , m.traceday
     , m.logtimestamp
  from flow f
  join messageinfo m 
    on m.flowid = f.flowid
  Join
     ( select flowid
            , max(traceid) traceid 
         from messageinfo 
        Group
           By flowid
     ) x
    On x.flowid = f.flowid
   And x.traceid = m.traceid
 order 
    by f.name
0 голосов
/ 11 июня 2018

Вы можете использовать индекс SQL для быстрого извлечения ваших данных.Вы не можете видеть индексы, они просто используются для ускорения поиска / запросов.Ниже приведен синтаксис для добавления индекса.

CREATE INDEX index_name
ON table_name (column1, column2, ...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...