Crearía los siguientes índices (índices de árbol b):
analytics(user_id, source, id)
transactions(analytics, status)
Esto es diferente de la sugerencia de Gordon.
El orden de las columnas en el índice es importante.
Filtra por analytics.user_id específico , por lo que este campo debe ser el primero en el índice. Luego, agrupe por analytics.source . Para evitar ordenar por source este debería ser el siguiente campo del índice. También hace referencia a analytics.id , por lo que es mejor tener este campo como parte del índice, colóquelo al final. ¿MySQL es capaz de leer solo el índice y no tocar la tabla? No sé, pero es bastante fácil de probar.
Índice de transactions tiene que empezar con analytics , porque se usaría en JOIN . También necesitamos 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