2016-11-16 3 views
0

У меня есть запрос, какКак ускорить подсчет из другой таблицы агрегации в mysql?

SELECT ProductId,(SELECT COUNT(*) 
         FROM Log 
         WHERE Log.App = App.No 
         AND Log.Event = 54 
         ) 
     FROM App 
     WHERE App.cat IN (1,2,3) 

Этот запрос возвращение 1 миллион записей. Проблема в том, что этот запрос очень медленный. У меня есть составной индекс для LOG (App, Event) и индекс для App (cat). Есть ли способ ускорить этот запрос? App и журнал таблица содержит около 10 миллионов записей

когда я закомментировать "SELECT COUNT(*) ...." запрос супер быстрый

+0

Вы _counting_ записи 1 миллион раз (!). Каково фактическое время отклика и каково ваше ожидание? – FDavidov

ответ

1

Вы можете попробовать переписывать запрос использовать объединение вместо коррелированных подзапросов:

SELECT t1.ProductId, 
     COALESECE(t2.logCount, 0) 
FROM App t1 
INNER JOIN 
(
    SELECT t1.No, COUNT(*) AS logCount 
    FROM App t1 
    LEFT JOIN Log t2 
     ON t1.No = t2.App AND 
      t2.Event = 54 
    WHERE t1.cat IN (1, 2, 3) 
    GROUP BY t1.No 
) t2 
    ON t1.No = t2.No 
+0

Что делать, если вы выполняете 'inner join' в' inner query' и 'left join' на' external query', не лучше ли это? – Shaharyar

+0

@Shaharyar Посмотрите внимательно, и вы поймете, почему это нежелательно. В исходном запросе он вычисляет счетчик для каждой записи, почти как функция окна. Поэтому каждая запись в 'App' появится в наборе результатов, даже если счетчик равен нулю. Если бы мы были «INNER JOIN», записи из «App», которые не соответствуют ни к чему, были бы отфильтрованы. Это изменит набор результатов из OP. –

+0

Внешняя 'INNER JOIN' в порядке, потому что нет никаких шансов на удаление каких-либо записей из' App t1'. –

0

You может использовать JOIN. Потому что подзапрос очень медленный.

SELECT ProductId, COUNT(Log.*) 
    FROM App 
    LEFT OUTER JOIN Log ON Log.App = App.No AND Log.Event = 54 
    WHERE App.cat IN (1,2,3) 
+0

Это не даст желаемых результатов, потому что это приведет к единому счету для всего запроса. –

+0

Да, я написал, что это может быть образец –

Смежные вопросы