Eu criaria os seguintes índices (índices b-tree):
analytics(user_id, source, id)
transactions(analytics, status)
Isso é diferente da sugestão de Gordon.
A ordem das colunas no índice é importante.
Você filtra por
analytics.user_id
específico , portanto, esse campo deve ser o primeiro no índice. Em seguida, você agrupa por analytics.source
. Para evitar a classificação por source
este deve ser o próximo campo do índice. Você também faz referência a analytics.id
, então é melhor ter este campo como parte do índice, coloque-o por último. O MySQL é capaz de ler apenas o índice e não tocar na tabela? Não sei, mas é bem fácil de testar. Índice em
transactions
tem que começar com analytics
, porque seria usado no JOIN
. Também precisamos de status
. SELECT
analytics.source AS referrer,
COUNT(analytics.id) AS frequency,
SUM(IF(transactions.status = 'COMPLETED', 1, 0)) AS sales
FROM analytics
LEFT JOIN transactions ON analytics.id = transactions.analytics
WHERE analytics.user_id = 52094
GROUP BY analytics.source
ORDER BY frequency DESC
LIMIT 10