Мой SQL работает очень медленно из-за `Order by` &` Limit`

0

У меня проблема с производительностью с запросом ниже на MYSQL. В приведенном ниже запросе участвуют 5 таблиц. Когда я применяю order by и limit, результаты получаются через 0,3 с. Но без order by и limit я смог получить результаты за 0,01 секунды. Я устал изменять запрос, но это не сработало. Может кто-то, пожалуйста, помогите мне с этим запросом, чтобы я мог получить результаты в нужное время (<0,3 сек).

Below are the details.

m_todos = 286579 (records)
m_pat = 214858 (records)
users = 119 (records)
m_programs = 26 (records)
role = 4 (records)


SELECT  *
    FROM (
        SELECT  t.*,
                mp.name as A_name,
                u.first_name, u.last_name,
                p.first, p.last, p.zone, p.language,p.handling,
                r.name,
                u2.first_name AS created_first_name,
                u2.last_name AS created_last_name
            FROM  m_todos t
            INNER JOIN  role r  ON t.role_id=r.id
            INNER JOIN  m_pat p  ON t.patient_id = p.id
            LEFT JOIN  users u2  ON t.created_id=u2.id
            LEFT JOIN  m_programs mp  ON t.prog_id=mp.id
            LEFT JOIN  users u  ON t.user_id=u.id
            WHERE  t.role_id !='9'
              AND  t.completed = '0000-00-00 00:00:00' 
         ) C
    ORDER BY  priority DESC, due ASC
    LIMIT  0,10
Теги:
performance

1 ответ

0

Избавьтесь от внешнего SELECT; переместите ORDER BY и LIMIT.

Индексы:

t:  (completed)
t:  (priority, due)

Я предполагаю, что priority и due в t?? Пожалуйста, будьте ясны в запросе. Это может иметь огромное значение.

Если следующее работает, это должно ускорить многое: начните с поиска t.id без всех JOINs:

SELECT id
    FROM m_todos
    WHERE  role_id !='9'
      AND  completed = '0000-00-00 00:00:00' 
    ORDER BY priority DESC, due DESC
    LIMIT 10

Это принесет пользу из этого охватывающего составного индекса:

INDEX(completed, role_id, priority, due, id)

Отлаживайте это. Затем используйте его в остальном:

SELECT t.*, the-other-stuff
    FROM ( that-query ) AS t1
    JOIN m_todos AS t  USING(id)
    then-the-rest-of-the-JOINs
    ORDER BY  priority DESC, due ASC   -- yes, again

Если вам не нужно все t.*, Может быть полезно указать фактические столбцы.

Причина этого заключается в том, что 10 строк найдены эффективно, глядя только на одну таблицу. Исходный код ковал вокруг намного большего количества строк, чем 10, и они включали все столбцы t, плюс столбцы из других таблиц.

Моя версия выполняет только 10 поисков для всех дополнительных материалов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню